使Foreach异步

时间:2015-10-06 07:08:38

标签: c# asynchronous foreach

考虑一种情况,我们必须调用一个方法,该方法又调用列表中的数据库foreach对象。

List<object> Response= new List<object>
foreach(object obj in List<object>)
{
    Resposne.add(callMethod());
}

如何运行这个foreach循环异步,我想为列表中的下一个对象调用callmethod而不等待第一个对象调用返回。成功返回所有调用后,控制权应返回给客户端。

由于callMethod函数调用数据库顺序执行需要时间。为了提高性能,我需要运行此异步。

2 个答案:

答案 0 :(得分:2)

  

我想为列表中的下一个对象调用callmethod而不等待第一个对象调用返回。

你真的想要parallelize your loop

List<object> Response= new List<object>();
// You need to put some stuff on Response
Parallel.ForEach(Response, o =>
{
   Response.Add(callMethod());
});

答案 1 :(得分:2)

您的callMethod()是一个IO操作,所以不要使用`Parallel.Foreach'。

Parallel.Foreach专为并行计算而设计。当您想要执行并行CPU密集型操作时,它可以很好地扩展。但是,如果调用同步IO操作,则将阻止该线程等待操作完成。这是浪费资源,因为线程在被阻塞时无法重用。更糟糕的是,调度程序将继续为`Parallel.Foreach'创建新线程以保持CPU忙。它可能不是客户端应用程序中的一个非常大的问题,但在具有许多并发请求的服务器应用程序中,它将成为瓶颈。

您应该进行callMethod()异步

private async Task<int> callMethodAsync()

在方法中进行异步操作,例如

using (SqlDataReader reader = await command.ExecuteReaderAsync())

然后像这样使用它:

int[] results = await Task.WhenAll(from obj in list select callMethodAsync());