Parallel.ForEach 和 async-await [英] Parallel.ForEach and async-await

查看:88
本文介绍了Parallel.ForEach 和 async-await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的方法:

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;
}

但现在我有一个错误:

异步模块或处理程序已完成,而异步操作仍处于挂起状态.

An asynchronous module or handler completed while an asynchronous operation was still pending.

推荐答案

async 不适用于 ForEach.特别是,您的 async lambda 正在转换为 async void 方法.有许多 避免async void 的原因(正如我在 MSDN 文章中所描述的);其中之一是您无法轻松检测 async lambda 何时完成.ASP.NET 将看到您的代码在未完成 async void 方法的情况下返回并(适当地)抛出异常.

async doesn't work well with ForEach. In particular, your async lambda is being converted to an async void method. There are a number of reasons to avoid async void (as I describe in an MSDN article); one of them is that you can't easily detect when the async lambda has completed. ASP.NET will see your code return without completing the async void method and (appropriately) throw an exception.

您可能想做的是并发处理数据,而不是并行.ASP.NET 上几乎不应该使用并行代码.下面是异步并发处理的代码:

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 和 async-await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆