即使指定TaskContinuationOptions,任务继续也始终运行 [英] Task continuations always run even when specifying TaskContinuationOptions

查看:83
本文介绍了即使指定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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆