即使指定TaskContinuationOptions,任务继续也始终运行 [英] Task continuations always run even when specifying TaskContinuationOptions
问题描述
我想在异步任务成功完成时运行一些代码。
I want to run some code when an async task completes successfully.
通过阅读网络上的文档和示例,我认为我可以使用 Task.ContinueWith
并指定 TaskContinuationOptions.OnlyOnRanToCompletion
。
From reading documentation and examples on the web, I thought I could use Task.ContinueWith
and specify TaskContinuationOptions.OnlyOnRanToCompletion
.
但是,这并不符合我的预期。
However, this doesn't behave as I expected.
以下代码是一个控制台程序,创建在Visual Studio 2012中,.Net 4.5:
The following code is a console program, created in Visual Studio 2012, .Net 4.5:
using System;
using System.Threading.Tasks;
namespace TaskContinueTest
{
class Program
{
static void Main(string[] args)
{
var jobTask = Task.Factory.StartNew(() => { });
jobTask.ContinueWith((task, options) =>
{
Console.WriteLine("Completed handler. Task status is {0}", task.Status);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
jobTask.ContinueWith((task, options) =>
{
Console.WriteLine("Faulted handler. Task status is {0}", task.Status);
}, TaskContinuationOptions.OnlyOnFaulted);
Console.ReadLine();
}
}
}
在运行时,我得到了输出:
when run, I get the output:
Completed handler. Task status is RanToCompletion
Faulted handler. Task status is RanToCompletion
,这非常令人惊讶(至少对我而言)。为什么要安排两个延续?
which is very surprising (at least to me). Why are both continuations scheduled?
如果我在 jobTask
中抛出异常,则会得到相同的行为,但是输出现在是:
I get the same behavior if I throw an exception in jobTask
, but the output is now:
Completed handler. Task status is Faulted
Faulted handler. Task status is Faulted
因此,框架清楚地知道了任务的状态,但是为什么两个继续
So the framework clearly knows the status of the task, but why are both continuations still scheduled?
推荐答案
我认为问题在于您不小心致电了此重载
I think the problem is that you're accidentally calling this overload
public Task ContinueWith(
Action<Task, Object> continuationAction,
Object state
)
您想要的是此重载:
public Task ContinueWith(
Action<Task> continuationAction,
TaskContinuationOptions continuationOptions
)
您只需要更改lambda表达式即可使用单个参数:
You just need to change your lambda expressions to use a single parameter:
Task.ContinueWith(task => Console.WriteLine(...),
TaskContinuationOptions.OnlyOnRanToCompletion);
这篇关于即使指定TaskContinuationOptions,任务继续也始终运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!