为什么先执行 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
,并且理想情况下不使用同步上下文。在最坏的情况下,所有调用都将被序列化。好吧,真的,在绝对最坏的情况下,你会陷入僵局,但是...... :)
我想用 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
,并且理想情况下不使用同步上下文。在最坏的情况下,所有调用都将被序列化。好吧,真的,在绝对最坏的情况下,你会陷入僵局,但是...... :)