【问题标题】:Task Parallel Library - How do you get a Continuation with TaskContinuationOptions.OnlyOnCanceled to Fire?任务并行库 - 如何通过 TaskContinuationOptions.OnlyOnCanceled 获得继续触发?
【发布时间】:2010-10-18 01:20:27
【问题描述】:

我正在试验 .NET 4.0 中的任务支持 - 特别是继续支持。我感到困惑的是,我无法弄清楚如何通过设置为执行的TaskContinuationOptions.OnlyOnCanceled 标志来继续。如果我在我的工作例程中执行ThrowIfCancellationRequested,它似乎只会作为错误而不是取消操作传播出延续。例如,给定以下代码:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace TaskExp1
{
    class Program
    {
        static void Main()
        {
            var n = 10000;

            DumpThreadId("main method");

            var cts = new CancellationTokenSource();
            var task = Task.Factory.StartNew<int>(_ => Sum(cts.Token, n), 
                                                  cts.Token);

            task.ContinueWith(t =>
            {
                DumpThreadId("ContinueWith Completed, ", newline:false);
                Console.WriteLine("The result is " + t.Result);
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            task.ContinueWith(t =>
            {
                DumpThreadId("ContinueWith Faulted, ", newline: false);
                Console.WriteLine(t.Exception.InnerExceptions[0].Message);
            }, TaskContinuationOptions.OnlyOnFaulted);

            task.ContinueWith(_ =>
            {
                DumpThreadId("ContinueWith Cancelled, ");
            }, TaskContinuationOptions.OnlyOnCanceled);

            Console.WriteLine("Computing sum of " + n + " ...");
            Thread.SpinWait(100000);
            cts.Cancel();

            Console.WriteLine("Done.");
            Console.ReadLine();
        }

        static int Sum(CancellationToken cancelToken, int n)
        {
            DumpThreadId("from Sum method");
            int sum = 0;
            for (; n > 0; n--)
            {
                Thread.SpinWait(500000);
                if (n == 10000) cancelToken.ThrowIfCancellationRequested();
                checked { sum += n; }
            }
            return sum;
        }

        static void DumpThreadId(string msg = "", bool newline = true)
        {
            var formattedMsg = String.Format("ThreadId: {0} {1}", 
                                  Thread.CurrentThread.ManagedThreadId, msg);
            if (newline) formattedMsg += "\n";
            Console.Write(formattedMsg);
        }
    }
}

这个输出:

ThreadId: 9 main method
Computing sum of 10000 ...
Done.
ThreadId: 10 from Sum method
ThreadId: 10 ContinueWith Faulted, The operation was canceled.

如何退出我的工作 (Sum) 方法,以便触发 OnlyOnCanceled 延续?

【问题讨论】:

    标签: task-parallel-library parallel-extensions


    【解决方案1】:

    当您使用 _ => lambda 表达式时,您正在使用

    Func<Object, TResult> function, Object state
    

    过载。如果您将 Factory.StartNew 更改为

    Task.Factory.StartNew<int>(() => Sum(cts.Token, n), cts.Token);
    

    它将调用“ContinueWith Cancelled”。

    【讨论】:

    • 哇,这看起来很微妙但很有意义 - 使用 _ != 来使用 ()。谢谢!
    猜你喜欢
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多