【发布时间】:2016-11-16 21:46:01
【问题描述】:
我想遍历一组 db 连接字符串并对所有数据库执行查询,然后将每个 IEnumberable 结果合并到一个 IEnumerable 列表中。同步版本如下所示:
public ActionResult ListSites()
{
ConnectionStringSettingsCollection ConnectionStrings = ConfigurationManager.ConnectionStrings;
List<SiteInfoModel> lstSites = new List<SiteInfoModel>();
foreach (ConnectionStringSettings cn in ConnectionStrings)
{
lstSites.AddRange(getSitesForInstance(cn));
}
return View("~/Views/Sites/List.cshtml", lstSites);
}
private List<SiteInfoModel> getSitesForInstance(ConnectionStringSettings css)
{
using (STContext db = new STContext(css.ConnectionString))
{
IEnumerable<SiteTracker.Data.site_info> sites = db.Sites;
return (from s in sites
orderby s.name
select new SiteInfoModel
{
instance = css.Name,
siteName = formatValue(s.name, s.active),
siteUrl = formatValue(s.url, s.active),
siteId = s.site_id,
isActive = s.active
}).ToList();
}
}
这个问题可能有几个子问题,因为我感觉我在为几个不同的事情苦苦挣扎:(1) getSitesForInstance() 应该如何编写?应该是
private async Task<List<SiteInfoModel>> getSitesForInstance()
如果它应该是异步的,那么我该如何编写 linq 表达式。我尝试将 IEnumerable 更改为 IQueryable 并使用 .ToListAsync() 但我收到有关投影非匿名类型的错误。是否可以在没有 async Task 的情况下编写它并且仍然让查询在所有连接字符串中同时执行?如果它可以通过任何一种方式完成,是更好还是更差。
问题的另一部分是 (2) ListSites() 在编写以进行并发数据库调用时应该如何看待?我看过this example,但它并没有让我找到一个可行的解决方案。我玩过这样的东西:
Task<List<SiteInfoModel>>[] tasks = new Task<List<SiteInfoModel>>[ConnectionStrings.Count];
for (int i = 0; i < ConnectionStrings.Count - 1; i++)
{
tasks[i] = getSitesForInstance(ConnectionStrings[i]);
}
Task.WaitAll(tasks);
...但无法正常工作。每个数据库调用都返回一个列表。当所有任务的结果组合到变量 lstSites(即视图模型)中时,问题/问题就得到了解决/回答。
【问题讨论】:
-
不知道为什么人们投票关闭 - 但我也不确定为什么它不起作用。您的异步版本到底有什么问题?我在一个运行良好的应用程序中做了类似的事情。
标签: c# asp.net-mvc linq asynchronous task-parallel-library