2010-10-18 72 views
4

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

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. 

如何退出我的工人(和)方式使得OnlyOnCanceled继续被解雇?

回答

5

当您使用_ =>λ表达式正在使用的

Func<Object, TResult> function, Object state 

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

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

它将调用“ContinueWith Canceled”。

+0

哇,这似乎很微妙,但有道理 - 使用_!=使用()。谢谢! – 2010-11-17 00:02:21