2012-06-01 88 views
19

下面是一个示例代码,它创建了一个模拟长时间运行的进程的新任务。没有什么太多的任务是纯粹关注取消功能的。我使用取消令牌来取消任务,并且代码正常工作为了我。将CancellationToken传递给Task类的构造函数有什么用?

 CancellationTokenSource CTS= new CancellationTokenSource(); 

     Task<Boolean> PTask = new Task<Boolean>(() => 
     { 
      while (true) 
      { 
       if (!CTS.Token.IsCancellationRequested) 
       { 
        Thread.Sleep(5000); 
       } 
       else{Console.WriteLine("Thread Cancelled");break;} 
      } 
      return true; 

     }, CTS.Token, TaskCreationOptions.None); 

     PTask.Start(); 
     Console.WriteLine("Hit Enter to cancel the Secondary thread you have started"); 
     Console.ReadLine(); 
     CTS.Cancel(); 
     System.Console.WriteLine(PTask.Result); 

    } 
} 

但onething是我无法理解的是,被传递到任务Constructor.What令牌参数(CTS.Token)是实际使用传递参数,当我其实可以取消任务即使没有将令牌传递给构造函数。

下面是一个略有修改的版本,没有token参数。

 CancellationTokenSource CTS= new CancellationTokenSource(); 
     Task<Boolean> PTask = new Task<Boolean>(() => 
     { 
      while (true) 
      { 
       if (!CTS.Token.IsCancellationRequested) 
       { 
        Thread.Sleep(5000); 
       } 
       else 
       { 
        Console.WriteLine("Thread Cancelled"); 
        break; 
       } 
     }; 
+1

我会推荐阅读:http://blogs.msdn.com/b/pfxteam/archive/2009/05/22/9635790.aspx – Slugart

回答

35

UPDATE: 以下msdn问题描述的原因:与任务令牌关联

传递令牌到StartNew。 这有两个主要优点:

  1. 如果令牌有取消 任务之前,请开始执行,任务将无法执行 。它将立即 转换到已取消,而不是过渡到运行。这样可以避免运行任务的成本,如果 只是在运行时才会被取消。

  2. 如果 任务的身体也监测取消标记并抛出 OperationCanceledException包含令牌(这是什么 ThrowIfCancellationRequested那样),那么当任务看到OCE, 它检查是否OCE的令牌匹配任务的标记。如果它是 ,那么此例外情况将视为确认合作伙伴取消,并且任务转换为取消状态(而不是故障状态的 )。

+0

你说的iscancelrequest与主令牌检查线程不安全。 –

+0

我看不到任何将令牌传递给构造函数的其他原因,但是如果你问我是否100%确定;不好。 – daryal

+0

我已更新,实际上这与线程安全无关。 – daryal

相关问题