SB2*_*055 4 .net c# task task-parallel-library async-await
在以下代码中:
if (await Task.WhenAny(task, Task.Delay(100)) == task) {
success = true;
}
else {
details += "Timed out on SendGrid.";
await task.ContinueWith(s =>
{
LogError(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
}
Run Code Online (Sandbox Code Playgroud)
我偶尔会A task was cancelled
接到电话await task.ContinueWith
.我的目标是看看是否task
在100ms内完成 - 如果没有,我想处理一些日志记录(这个特定任务有资源泄漏,所以我试图通过将其包装在超时中来解决它).这是从这里的指导中提取的: Debugging Task.WhenAny和Push Notifications
为什么会发生这种情况,我该怎么做才能防止抛出此异常?
当你task
无法及时完成时(100毫秒)但是能够在以后完成时会发生这种情况.TaskContinuationOptions.OnlyOnFaulted
如果原始任务没有出现故障,则运行继续操作并取消此类任务.你await
造成的ContinueWith
,所以如果你的任务没有故障-你继续被取消,你有一个例外.
通常这种处理超时的方法没有多大意义,因为即使在达到超时之后,您仍然要等到原始任务完成,才能记录异常.我想你必须await
在继续之前删除.然后代码将在超时时继续,但如果任务稍后失败 - 它将被记录.
您的代码中还有另一个问题 - Task.WhenAny
永远不会抛出.所以这个条件:
await Task.WhenAny(task, Task.Delay(100)) == task
Run Code Online (Sandbox Code Playgroud)
并不意味着成功,因为task
可能会出现问题.始终检查task.Status
,task.Exception
即使WhenAny
表明您的任务已完成.顺便说一句,您在问题中链接的答案提到了这一点.
更新:如果您不喜欢关于未等待电话的VS警告 - 您可以为此特定行禁用它,或使用如下扩展方法:
static class TaskExtensions
{
public static void Forget(this Task task)
{
// do nothing
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
task.ContinueWith(s => {
Logger.Write(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted).Forget();
Run Code Online (Sandbox Code Playgroud)
这样做是没有害处的(当然在这个特殊情况下),VS只是在每个可能等待的等待的电话上发出这个警告.
归档时间: |
|
查看次数: |
1503 次 |
最近记录: |