问题
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").
Why?
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);
}
回答1:
You're binding your continuations wrong.
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." :)
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?
来源:https://stackoverflow.com/questions/37567142/why-does-the-onlyoncanceled-continuation-get-called