C# 为什么先执行Return语句而不是并行语句。弗雷奇

C# 为什么先执行Return语句而不是并行语句。弗雷奇,c#,parallel.foreach,C#,Parallel.foreach,我想使用Parallel.ForEach操作一个集合并返回另一个集合。但我似乎得到了一个空的方法,还有一个异步方法需要并行执行 这是windows 10中带有netcore2.2的控制台应用程序 publicstaticconcurrentbag GetList() { ConcurrentBag结果=新ConcurrentBag(); 列表=新列表{1,2,3}; Parallel.ForEach(列表,异步i=>{ 等待任务。延迟(i*1000); 结果.增加(i*2); }); 返回结果;

我想使用Parallel.ForEach操作一个集合并返回另一个集合。但我似乎得到了一个空的方法,还有一个异步方法需要并行执行

这是windows 10中带有netcore2.2的控制台应用程序

publicstaticconcurrentbag GetList()
{
ConcurrentBag结果=新ConcurrentBag();
列表=新列表{1,2,3};
Parallel.ForEach(列表,异步i=>{
等待任务。延迟(i*1000);
结果.增加(i*2);
});
返回结果;
}
公共静态void Main(字符串[]args)
{
列表=新列表();
var res=GetList();
列表。添加范围(res);
控制台。写线(“乞讨”);
foreach(列表中的变量项)
{
控制台写入线(项目);
}
Console.ReadLine();
}

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

wait
是罪魁祸首。您需要了解的是,
wait
是一种奇特的回报。如果调用方不理解任务,那么它看到的只是返回
Parallel.ForEach
不希望委托返回任务,因此它不知道如何等待
wait
完成

Parallel.ForEach
几乎一开始就完成了,而且在写入
结果之前很久

现在,
Parallel
应该用于CPU限制的操作,所以这不是问题。如果要模拟长时间运行的CPU绑定操作,请使用
Thread.Sleep
而不是
wait Task.Delay

作为旁注,如何并行化受I/O限制的基于任务的操作?最简单的方法如下:

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

其中,
YourAsyncOperation
是一种返回
Task
的异步方法,它可以使用
Task.Delay
任意延迟。这种简单方法的主要问题是,您必须确保
YourAsyncOperation
实际上很快就会执行
Wait
,理想情况下不使用同步上下文。在最坏的情况下,所有调用都将被序列化。嗯,真的,在绝对最坏的情况下,你会陷入僵局,但是……:)

为什么要使用
async
wait Task.Delay(i*1000)<代码>并行.Frace与<代码>异步代码>代码不太好。您可能需要考虑的是<代码>返回列表。AsParallel(Studio)。代码>。我的意思是,这是毫无意义的,但它会给你并行性。不要对异步代码使用
Parallel.ForEach
。它仅用于数据并行,不能等待任何任务。您所做的是启动一系列任务,这些任务甚至可能在应用程序终止之前都无法运行。Parallel.ForEach无法等待这些任务ConcurrentBag也不是一个好选择。与其他并发集合不同,它是一个专门的类,使用线程本地存储来允许更快地访问创建对象的线程。这意味着与使用ConcurrentQueue相比,主线程读取结果所需的时间更长