为什么先执行 Return 语句而不是 Parallel.对于每个

Why execute the Return statement first instead of the Parallel. ForEach

我想用 Parallel.ForEach 操纵一组,return 操纵另一组。但是我好像得到了一个空one.AndParallel.ForEach里面有一个异步方法需要执行。

这是一个在 windows 10 中使用 netcore2.2 的控制台应用程序。

        public static ConcurrentBag<int> GetList()
        {
            ConcurrentBag<int> result = new ConcurrentBag<int>() ;
            List<int> list = new List<int> { 1, 2, 3 };
            Parallel.ForEach(list, async i => {
                await Task.Delay(i*1000);
                result.Add(i * 2);
            });
            return result;
        }
        public static void Main(String[] args)
        {
            List<int> list = new List<int>();
            var res = GetList();
            list.AddRange(res);
            Console.WriteLine("Begging.");
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }

我期望 {2,4,6},但实际上是一个空的。

await 是罪魁祸首。您需要了解的是 await 是花哨的 return。如果调用者不理解任务,它看到的只是 return。 Parallel.ForEach 不期望委托 return 的任务,因此它不知道如何等待 await 完成。

Parallel.ForEach 几乎一开始就完成,并且在任何内容写入 result 之前很久就完成了。

现在,Parallel 应该用于 CPU 绑定操作,所以这不是问题。如果要模拟 long-运行 CPU-bound 操作,请使用 Thread.Sleep 而不是 await Task.Delay.

附带说明一下,您将如何并行化 I/O 绑定的基于任务的操作?最简单的方法是这样的:

await Task.WhenAll(list.Select(YourAsyncOperation));

其中 YourAsyncOperation 是一个异步方法 returning Task,它可以根据需要使用 Task.Delay。这种简单方法的主要问题是您 必须 确保 YourAsyncOperation 实际上很快就会执行 await,并且理想情况下不使用同步上下文。在最坏的情况下,所有调用都将被序列化。好吧,真的,在绝对最坏的情况下,你会陷入僵局,但是...... :)