为什么调用OnlyOnCanceled延续? [英] Why does the OnlyOnCanceled continuation get called?
问题描述
在下面的代码上调用 await RunAsync();
时,我希望继续运行 TaskContinuationOptions.OnlyRanToCompletion
延续,但是 OnlyOnCanceled 代码>连续被调用(产生调试输出任务已取消").
When calling await RunAsync();
on the below code, I would expect the continuation with TaskContinuationOptions.OnlyRanToCompletion
continuation to run, however the OnlyOnCanceled
continuation gets called (yielding the debug output "Task canceled").
为什么?
private static async Task RunAsync()
{
try
{
await Task.Run(() => DoWork())
.ContinueWith(
(t) =>
{
if (t?.Exception != null)
{
throw t.Exception;
}
}, TaskContinuationOptions.OnlyOnFaulted
).ContinueWith(
(t) =>
{
Debug.WriteLine("Task canceled.");
}, TaskContinuationOptions.OnlyOnCanceled
).ContinueWith(
(t) =>
{
Debug.WriteLine("Task completed.");
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private static void DoWork()
{
Thread.Sleep(1000);
}
推荐答案
您将续订绑定错误.
您不是在"main"任务中添加三个延续,而是在延续中添加了延续.当主要任务正确完成时, OnlyOnFaulted
延续将被取消,这会触发您错误地将 OnlyOnCanceled
延续连接到 OnlyOnFaulted
延续而不是主要任务.然后最好的部分-这意味着第二个延续正确完成,并且由于您在第二个延续上连接了最后一个延续,所以最后一个延续也将运行,因此完整输出为任务已取消.任务已完成".:)
Instead of adding three continuations to the "main" task, you're adding a continuation to a continuation to a continuation. When the main tasks finishes without error, the OnlyOnFaulted
continuation gets cancelled, which triggers the OnlyOnCanceled
continuation you incorrectly wired to the OnlyOnFaulted
continuation instead of the main task. And then the best part - this means that the second continuation finished correctly, and since you wired your last continuation on the second continuation, the final continuation runs as well, so the full output is "Task canceled. Task completed." :)
不过,您所期望的正确输出并不明显.为什么首先要使用延续? await
为您提供的服务比手动完成的要好得多.混合 await
和 ContinueWith
很少是一个好主意:)您是否要尝试 await
主要任务(抛出异常时失败)?还是延续之一?还是仅仅是 OnlyOnRanToCompletion
的延续(这就是您现在正在做的事情,并且它永远不会以您期望的方式工作)?如果这种延续没有机会继续下去怎么办?
It's not obvious what you're expecting to be the correct output, though. Why are you using continuations in the first place? await
handles that for you much more nicely than you can ever do manually. Mixing await
and ContinueWith
is rarely a good idea :) Are you trying to await
the main task (failing when an exception is thrown)? Or one of the continuations? Or just the OnlyOnRanToCompletion
continuation (that's what you're doing right now, and it's never going to work the way you expect it to work)? What if that continuation never gets a chance to run?
这篇关于为什么调用OnlyOnCanceled延续?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!