即使指定TaskContinuationOptions,任务延续也始终运行

时间:2013-01-19 12:09:03

标签: c# asynchronous task-parallel-library .net-4.5

我想在异步任务成功完成时运行一些代码。

通过阅读网络上的文档和示例,我想我可以使用Task.ContinueWith并指定TaskContinuationOptions.OnlyOnRanToCompletion

然而,这并不像我预期的那样。

以下代码是在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();
        }
    }
}

运行时,我得到输出:

Completed handler. Task status is RanToCompletion
Faulted handler. Task status is RanToCompletion

这是非常令人惊讶的(至少对我而言)。为什么要安排两个延期?

如果我在jobTask中抛出异常,我会得到相同的行为,但输出现在是:

Completed handler. Task status is Faulted
Faulted handler. Task status is Faulted

所以框架清楚地知道任务的状态,但为什么两个延续仍然安排?

1 个答案:

答案 0 :(得分:5)

我认为问题在于你不小心打电话给this overload

public Task ContinueWith(
    Action<Task, Object> continuationAction,
    Object state
)

你想要的是this overload

public Task ContinueWith(
    Action<Task> continuationAction,
    TaskContinuationOptions continuationOptions
)

您只需要将lambda表达式更改为使用单个参数:

Task.ContinueWith(task => Console.WriteLine(...),
    TaskContinuationOptions.OnlyOnRanToCompletion);