Jon*_*gon 13 c# task async-await
我有两个任务。我用 Task.WhenAll 运行它们。如果其中一个抛出异常会发生什么?另一个会完成吗?
只需运行此代码来测试它:
private static async Task TestTaskWhenAll()
{
try
{
await Task.WhenAll(
ShortOperationAsync(),
LongOperationAsync()
);
}
catch (Exception exception)
{
Console.WriteLine(exception.Message); // Short operation exception
Debugger.Break();
}
}
private static async Task ShortOperationAsync()
{
await Task.Delay(1000);
throw new InvalidTimeZoneException("Short operation exception");
}
private static async Task LongOperationAsync()
{
await Task.Delay(5000);
throw new ArgumentException("Long operation exception");
}
Run Code Online (Sandbox Code Playgroud)
调试器将在 5 秒后停止。两个异常都被抛出,但Debugger.Break()只被命中一次。更重要的是,该exception值不是AggregateException,而是InvalidTimeZoneException。这是因为 newasync/await将解包到实际异常中。您可以在此处阅读更多内容。如果您想阅读其他内容Exceptions(不仅是第一个),则必须Task从WhenAll方法调用返回的内容中读取它们。
它不会因为另一个失败而停止。
Task.When将等待所有完成,无论有没有失败。我只是用这个测试来验证 - 花了 5 秒钟才能完成:
Task allTasks = Task.WhenAll(getClientToken, getVault, Task.Delay(5000));
Run Code Online (Sandbox Code Playgroud)
如果你想对任务进行分组,你可以创建一个“新任务”,然后等待。
Task allTasks = Task.WhenAll(getClientToken, getVault, Task.Delay(5000));
try
{
await allTasks;
} catch (Exception ex)
{
// ex is the 'unwrapped' actual exception
// I'm not actually sure if it's the first task to fail, or the first in the list that failed
// Handle all if needed
Exceptions[] allExceptions = allTasks.Exceptions;
// OR
// just get the result from the task / exception
if (getVault.Status == TaskStatus.Faulted)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
有同样的问题并亲自测试过。简而言之:
它总是等待所有任务完成。
如果所有任务完成后有任何异常,则会抛出第一个异常(如果不捕获则会崩溃)。
对于所有异常,请保留and use属性Task返回的实例。Task.WhenAllException.InnerExceptions
这是我的测试:
static async Task Main(string[] args)
{
var tasks = new[] { Foo1(), Foo2(), Foo3() };
Task t = null;
try
{
t = Task.WhenAll(tasks);
await t;
}
catch (Exception ex)
{
Console.WriteLine($"{ex.GetType().Name}: {ex.Message}");
}
Console.WriteLine("All have run.");
if (t.Exception != null)
{
foreach (var ex in t.Exception.InnerExceptions)
{
Console.WriteLine($"{ex.GetType().Name}: {ex.Message}");
}
}
}
static async Task Foo1()
{
await Task.Delay(50);
throw new ArgumentException("zzz");
}
static async Task Foo2()
{
await Task.Delay(1000);
Console.WriteLine("Foo 2");
throw new FieldAccessException("xxx");
}
static async Task Foo3()
{
for (int i = 0; i < 10; i++)
{
await Task.Delay(200);
Console.WriteLine("Foo 3");
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Foo 3
Foo 3
Foo 3
Foo 3
Foo 2
Foo 3
Foo 3
Foo 3
Foo 3
Foo 3
Foo 3
ArgumentException: zzz
All have run.
ArgumentException: zzz
FieldAccessException: xxx
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5739 次 |
| 最近记录: |