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

查看:28
本文介绍了即使在指定 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();
        }
    }
}

运行时,我得到输出:

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天全站免登陆