在这段代码中:
private async void button1_Click(object sender, EventArgs e) {
try {
await Task.WhenAll(DoLongThingAsyncEx1(), DoLongThingAsyncEx2());
}
catch (Exception ex) {
// Expect AggregateException, but got InvalidTimeZoneException
}
}
Task DoLongThingAsyncEx1() {
return Task.Run(() => { throw new InvalidTimeZoneException(); });
}
Task DoLongThingAsyncEx2() {
return Task.Run(() => { throw new InvalidOperation();});
}
Run Code Online (Sandbox Code Playgroud)
我期望WhenAll创建并抛出一个AggregateException,因为至少有一个等待抛出异常的任务.相反,我正在收回其中一个任务抛出的单个异常.
难道WhenAll不总是创造AggregateException?
我有一个循环,在循环内我正在做:
await Task.Delay(1000, ct).ContinueWith(async _ =>
{
await SecondMethodAsync(ct);
});
Run Code Online (Sandbox Code Playgroud)
第二种方法使用 EF 获取实体,设置一些属性并通过await SaveChangesAsync()调用DbContext.
上面应该等待1s然后继续第二种方法。通过上述实现,我得到以下异常:
在上一个异步操作完成之前,第二个操作在此上下文上启动。使用“await”确保在此上下文上调用另一个方法之前所有异步操作已完成。不保证任何实例成员都是线程安全的。
当我将上面的内容更改为:
await Task.Delay(1000, ct);
await SecondMethodAsync(ct);
Run Code Online (Sandbox Code Playgroud)
一切正常。
上面的两个片段有什么区别?如何使第一个片段起作用?
我正在测试 C# async/await 的异步性,遇到了一个惊喜,即 ContinueWith 的后续代码不等待前一个任务完成:
public async Task<int> SampleAsyncMethodAsync(int number,string id)
{
Console.WriteLine($"Started work for {id}.{number}");
ConcurrentBag<int> abc = new ConcurrentBag<int>();
await Task.Run(() => { for (int count = 0; count < 30; count++) { Console.WriteLine($"[{id}] Run: {number}"); abc.Add(count); } });
Console.WriteLine($"Completed work for {id}.{number}");
return abc.Sum();
}
Run Code Online (Sandbox Code Playgroud)
这是使用以下测试方法执行的:
[Test]
public void TestAsyncWaitForPreviousTask()
{
for (int count = 0; count < 3; count++)
{
int scopeCount = count;
var c = SampleAsyncMethodAsync(0, scopeCount.ToString())
.ContinueWith((prevTask) =>
{
return SampleAsyncMethodAsync(1, scopeCount.ToString()); …Run Code Online (Sandbox Code Playgroud)