我有这样的方法:
public async Task<MyResult> GetResult()
{
MyResult result = new MyResult();
foreach(var method in Methods)
{
string json = await Process(method);
result.Prop1 = PopulateProp1(json);
result.Prop2 = PopulateProp2(json);
}
return result;
}
然后我决定使用Parallel.ForEach
:
public async Task<MyResult> GetResult()
{
MyResult result = new MyResult();
Parallel.ForEach(Methods, async method =>
{
string json = await Process(method);
result.Prop1 = PopulateProp1(json);
result.Prop2 = PopulateProp2(json);
});
return result;
}
但现在我遇到了一个错误:
异步模块或处理程序已完成,而异步操作仍处于挂起状态。
async
不能很好地配合ForEach
。特别是,您的async
lambda 正在转换为async void
方法。有许多避免的理由async void(正如我在 MSDN 文章中所描述的);其中之一是您无法轻易检测到async
lambda 已完成。 ASP.NET 将看到您的代码在未完成的情况下返回async void
方法并(适当地)抛出异常。
您可能想要做的是处理数据同时,只是不在parallel。并行代码几乎不应该在 ASP.NET 上使用。以下是异步并发处理的代码:
public async Task<MyResult> GetResult()
{
MyResult result = new MyResult();
var tasks = Methods.Select(method => ProcessAsync(method)).ToArray();
string[] json = await Task.WhenAll(tasks);
result.Prop1 = PopulateProp1(json[0]);
...
return result;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)