在 ADO.Net C# 中执行并行数据库访问
Posted
技术标签:
【中文标题】在 ADO.Net C# 中执行并行数据库访问【英文标题】:Execute parallel database access in ADO.Net C# 【发布时间】:2016-09-09 14:06:42 【问题描述】:我正在开发 asp.net 应用程序以在仪表板上显示多个小部件。所以我发送了一个 ajax 调用来获取仪表板小部件所需的所有数据。
在服务器方法内部,有多个数据库调用通过存储过程从数据库中获取每个小部件的相关数据。方法内容如下;
List<DashboardItem> items = new List<DashboardItem>();
items.Add(GetUserList());
items.Add(GetNewsList());
items.Add(GetRecentlyViewedList());
items.Add(GetSentEmailsList());
.....
return items;
由于数据库中没有记录,这个过程似乎很慢。
我正在尝试使用异步数据库调用执行上述代码。似乎异步数据库操作可以改善这个过程。谁能帮我写异步数据库操作?或任何其他提高数据库方法调用性能的建议?
【问题讨论】:
dotnetcodr.com/2014/01/01/5-ways-to-start-a-task-in-net-c 在您的 GetXXX 上使用带有await
关键字的异步版本的数据库连接器,然后返回 DashboardItem[]
而不是返回 Task<DashboardItem[]>
,然后您可以创建一个 List<Task<DashboardItem[]>>
,添加返回的来自这些函数的任务,然后执行await Task.WaitAll(theListOfTasks)
,最后使用列表中存储的每个任务的.Result
。
不要尝试并行执行查询,只需将它们全部批处理。 NHibernate 允许批处理,EF 可以使用扩展批处理查询。只有当您必须在多个网卡上移动 很多(想想 GB)的数据数据时,并行执行才有帮助。否则,您只需引入更多的并发开销并使用比需要更多的连接
@Gusman 使用像 WaitAll
这样的阻塞方法是一个坏的想法。重点是减少阻塞。 await Task.WhenAll()
不会阻止。
@Aruna 不,这不会导致延迟,除非 SP没有写得很好。顺便说一句,原始 SQL 查询与存储过程之间没有性能差异。 确实 导致延迟的是建立多个连接和不必要的往返。您可以将所有呼叫批量处理,只需支付单次往返费用。
【参考方案1】:
您需要将您的入口点标记为Task
返回,然后您可以使用async
和await
关键字。此外,GetUserList
、GetNewsList
、GetRecentlyViewedList
和 GetSentEmailsList
方法也必须返回 Task
,这样你就可以一直使用 async
——(注意将 Async 添加到表明其性质的方法)。
public async Task GetDashboardItemsAsync()
var getUserTask = GetUserListAsync();
var getNewsTask = GetNewsListAsync();
var getRecentlyViewedTask = GetRecentlyViewedListAsync();
var getSentEmailsTask = GetSentEmailsListAsync();
await Task.WhenAll(getUserTask,
getNewsTask,
getRecentlyViewedTask,
getSentEmailsTask);
return new List<DashboardItem>
getUserTask.Result,
getNewsTask.Result,
getRecentlyViewedTask.Result,
getSentEmailsTask.Result,
;
将任务存储在变量中将允许您在它们全部实现后访问.Result
。 Task.WhenAll
方法采用 Task
数组,一旦所有这些都完成,它将继续。
使用这种方法,您基本上是在说启动每个任务以获取仪表板数据,一旦所有异步操作运行完成,然后继续将DashboardItem
的列表返回给调用者。
这主要是解决调用代码以及如何以并行方式处理多个任务。为了在 ADO.NET 级别启动提取操作,这应该是一个不同的问题。但是ADO.NET 和Entity Framework 上也有很多
async
API。
【讨论】:
以上是关于在 ADO.Net C# 中执行并行数据库访问的主要内容,如果未能解决你的问题,请参考以下文章