Parallel.ForEach和异步的await [英] Parallel.ForEach and async-await
问题描述
我有这样的方法:
公共异步任务< MyResult>调用getResult()
{
MyResult结果=新MyResult(); 的foreach(在方法VAR法)
{
JSON字符串等待=程序(方法); result.Prop1 = PopulateProp1(JSON);
result.Prop2 = PopulateProp2(JSON); } 返回结果;
}
然后我决定用 Parallel.ForEach
:
公共异步任务< MyResult>调用getResult()
{
MyResult结果=新MyResult(); Parallel.ForEach(方法,异步方法= GT;
{
JSON字符串等待=程序(方法); result.Prop1 = PopulateProp1(JSON);
result.Prop2 = PopulateProp2(JSON);
}); 返回结果;
}
但现在我已经得到了一个错误:
而异步操作仍然悬而未决的异步模块或处理程序完成。
块引用>解决方案
异步
不的ForEach
。特别是,你的异步
拉姆达被转换为异步无效
方法。有一些原因,以避免异步无效
(我描述了MSDN文章中);其中之一是,当异步
拉姆达已完成你不能轻易察觉。 ASP.NET会看到没有完成的异步无效
方法(适当地)抛出一个异常,你的code的回报。您可能想要做的是处理数据的同时的,只是没有在的平行的。并行code应该几乎从不在ASP.NET中使用。这里的code会是什么样子异步并行处理:
公共异步任务< MyResult>调用getResult()
{
MyResult结果=新MyResult(); VAR任务= Methods.Select(方法=> ProcessAsync(法))ToArray的()。
字符串[] = JSON等待Task.WhenAll(任务); result.Prop1 = PopulateProp1(JSON [0]);
... 返回结果;
}I had such method:
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; }
Then I decided to use
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; }
But now I've got an error:
An asynchronous module or handler completed while an asynchronous operation was still pending.
解决方案
async
doesn't work well withForEach
. In particular, yourasync
lambda is being converted to anasync void
method. There are a number of reasons to avoidasync void
(as I describe in an MSDN article); one of them is that you can't easily detect when theasync
lambda has completed. ASP.NET will see your code return without completing theasync void
method and (appropriately) throw an exception.What you probably want to do is process the data concurrently, just not in parallel. Parallel code should almost never be used on ASP.NET. Here's what the code would look like with asynchronous concurrent processing:
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; }
这篇关于Parallel.ForEach和异步的await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!