2016-03-21 3 views
8

(1)https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspxなぜキャンセルトークンをTaskFactory.StartNewに渡すのですか?唯一の「アクション」パラメータでTaskFactory.StartNewを呼び出すの最も一般的な形式のほかに

我々は (2)https://msdn.microsoft.com/en-us/library/dd988458.aspx

「キャンセリングトークン」などの追加パラメータを受け入れる一つの方法を持っているalse

私の質問は、call(1)の代わりにcall(2)を使用する理由は何ですか?変数トークンは、デリゲート関数からアクセス可能であるので、私は(パラメータとしてキャンセルトークンを渡さない場合、私は意味

、ページのためのMSDNの例では、(2)もうまくいくような何か:。

var tokenSource = new CancellationTokenSource(); 
     var token = tokenSource.Token; 
     var files = new List<Tuple<string, string, long, DateTime>>(); 

     var t = Task.Factory.StartNew(() => { string dir = "C:\\Windows\\System32\\"; 
           object obj = new Object(); 
           if (Directory.Exists(dir)) { 
            Parallel.ForEach(Directory.GetFiles(dir), 
            f => { 
              if (token.IsCancellationRequested) 
               token.ThrowIfCancellationRequested(); 
              var fi = new FileInfo(f); 
              lock(obj) { 
               files.Add(Tuple.Create(fi.Name, fi.DirectoryName, fi.Length, fi.LastWriteTimeUtc));   
              } 
             }); 
           } 
           } 
         ); //note that I removed the ", token" from here 
     tokenSource.Cancel(); 

だから私はTask.Factory.StartNewにキャンセルトークンを渡すときの下に起こって何がありますか?

おかげ

答えて

7

2つのことが起こります。

  1. StartNewが呼び出される前にトークンがキャンセルされてもスレッドは開始されず、タスクはCanceledの状態になります。
  2. OperationCanceledExceptionがタスク内から呼び出され、その例外がStartNewと同じトークンで渡された場合、返されたタスクはCancelled状態になります。例外に関連付けられたトークンが異なるトークンである場合、またはタスクにトークンを渡さなかった場合、Faulted状態になります。

P.S.TaskSchedulerを使わないでTask.Factory.StartNewに電話することは決してありません。なぜなら、もしそうでなければ、簡単にcause you to run code on the UI thread that you expected to run on a background threadができるからです。 StartNewを無条件に使用する必要がある場合を除き、Task.Run(を代わりに使用してください。は、同じCancellationTokenの動作をStartNewとしています。

+0

「Task.Factory」を使用しないことについてのご意見ありがとうございます – kai

関連する問題