Jon*_*nik 4 .net c# asynchronous exception parallel.foreach
有人可以解释一下这段代码的行为:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello world");
try
{
Parallel.ForEach(new[] { 1, 2, 3 }, async i =>
{
await Task.Delay(TimeSpan.FromSeconds(3));
throw new TaskCanceledException();
});
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Goodbye cruel world");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
怎么可能,异常在主线程中从“try”块中弹出,应用程序崩溃了。我知道并行异步的最佳方法是“Task.WhenAll”。问题的目的是了解行为。
Parallel.ForEach不能用于调用异步方法。它仅适用于内存中数据并行性,不适用于异步操作。它的工作原理是对数据进行分区,并将每批数据提供给一个工作任务,每个 CPU 核心大约使用一个工作人员。它甚至使用调用线程来处理这些分区之一,这就是它看起来“阻塞”的原因。
它的重载都不接受 a Task,这意味着本例中 lambda 的返回类型是async void。
该问题的代码相当于:
async void Do(int i)
{
await Task.Delay(TimeSpan.FromSeconds(3));
throw new TaskCanceledException();
}
Parallel.ForEach(data,Do);
Run Code Online (Sandbox Code Playgroud)
async void方法不能被等待,这意味着它们的异常也不能被调用者捕获。此代码async void使用 触发 3 个调用并立即返回。
在 .NET 6 中,您应该使用Parallel.ForEachAsync:
var data=new[] { 1, 2, 3 };
await Parallel.ForEachAsync(data, async (i,token) =>
{
await Task.Delay(TimeSpan.FromSeconds(3));
throw new TaskCanceledException();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
502 次 |
| 最近记录: |