【发布时间】:2022-01-22 10:50:15
【问题描述】:
我的代码是这样的:
public async Process()
{
try
{
var records = await this.provider.GetRecordsAsync(); // this method can throws 'DataStoreException' only
foreach(var record in records)
{
try
{
this.Do(record); // here is some exception and code goes to catch
record.Status = Status.Success;
await this.provider.UpdateAsync(record).ContinueWith(
task =>
{
task.Exception?.Handle(e =>
{
this.logger.LogError(e);
return true;
});
}, TaskContinuationOptions.NotOnRanToCompletion);
}
catch(Exception e)
{
record.Status = Status.Error;
/*line 106:*/ await this.provider.UpdateAsync(record).ContinueWith(
task =>
{
task.Exception?.Handle(e =>
{
this.logger.LogError(e);
return true;
});
}, TaskContinuationOptions.NotOnRanToCompletion);
}
}
}
catch (DataStoreException e)
{
this.logger.LogError(e);
}
catch (Exception e)
{
// Got TaskCanceledException here
}
}
在评论点我得到了TaskCanceledException。我想原因是混合await 和ContinueWith,但是有人可以解释一下,这里发生了什么? UpdateAsync 只能抛出 DataStoreException。所以TaskCanceledException thew by ContinueWith,但是没有取消令牌,代码甚至没有达到这一点task.Exception?.Handle
这是调用堆栈:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at ProjectTest.MyClass.<Process>d__6.MoveNext() in C:\Projects\ProjectTest\MyClass.cs:line 106
如果 try/catch 包围 this.provider.UpdateAsync(record) 而不是 ContinueWith 一切都很好并且代码按预期工作。
将await 和ContinueWith 混合使用真的是不好的做法吗?如果是,为什么?
【问题讨论】:
-
附带说明一下,您熟悉
finally块吗? -
除非您是专家并且有充分的理由,否则不要将
ContinueWith与async-await混为一谈。
标签: c# async-await .net-core-3.1