gpt4 book ai didi

c# - Task.WhenAny - 任务被取消

转载 作者:太空狗 更新时间:2023-10-30 00:48:49 25 4
gpt4 key购买 nike

在下面的代码中:

        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);
}

我偶尔会在调用 await task.ContinueWith 时得到 A task was cancelled。我的目标是查看 task 是否在 100 毫秒内完成 - 如果没有,我想处理一些日志记录(这个特定任务有资源泄漏,所以我试图通过将其包装在超时中)。这是从此处的指南中提取的:Debugging Task.WhenAny and Push Notifications

为什么会发生这种情况,我该怎么做才能防止抛出此异常?

最佳答案

当您的任务 无法及时(在 100 毫秒内)完成但能够稍后完成时,就会发生这种情况。您使用 TaskContinuationOptions.OnlyOnFaulted 运行您的延续,如果原始任务没有出错,则此类任务将被取消。您 await ContinueWith 的结果,因此如果您的任务没有出错 - 您的继续将被取消并且出现异常。

一般来说,这种处理超时的方式没有多大意义,因为即使在达到超时后,您仍然要等到原始任务完成,才能记录异常。我认为您必须在继续之前删除 await 。然后代码将在超时时继续,但如果任务稍后失败 - 它将被记录下来。

您的代码中还有另一个问题 - Task.WhenAny 永远不会抛出。所以这个条件:

await Task.WhenAny(task, Task.Delay(100)) == task

并不意味着成功,因为 task 可能出错。始终检查 task.Statustask.Exception,即使 WhenAny 指示您的任务已完成。顺便说一句,您在问题中链接的答案提到了这一点。

更新:如果你不喜欢 VS 关于未等待调用的警告 - 你可以为这个特定的线路禁用它,或者使用这样的扩展方法:

static class TaskExtensions
{
public static void Forget(this Task task)
{
// do nothing
}
}

然后:

task.ContinueWith(s => {
Logger.Write(s.Exception);
}, TaskContinuationOptions.OnlyOnFaulted).Forget();

这样做没有坏处(当然在这种特殊情况下),VS 只是在每个未等待的潜在可等待调用上发出此警告。

关于c# - Task.WhenAny - 任务被取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43240761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com