2010-10-18 149 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

相關問題