2011-10-27 24 views
21

これは、.NET 4のタスクAPIを使用して実行する必要があるバックグラウンドスレッドのための良い設計ですか?私の唯一の懸念は、私がそれをやる方法をその仕事をキャンセルしたいのですか? ProgramEndingtrueに設定することができますが、私はタスクAPIにCancellationTokenがあることを知っています。ベストプラクティスLongRunningタスクの作成

これは、1つのスレッドがコレクションに追加され、別のスレッドがそのスレッドから削除されるように、コードのサンプルの一例です。これは、プログラムが実行されている間、継続的に実行されている必要があり、タスクはLongRunningとして設定され

private void RemoveFromBlockingCollection() 
{ 
    while (!ProgramEnding) 
    { 
     foreach (var x in DataInQueue.GetConsumingEnumerable()) 
     { 
      Console.WriteLine("Task={0}, obj={1}, Thread={2}" 
          , Task.CurrentId, x + " Removed" 
          , Thread.CurrentThread.ManagedThreadId); 
     } 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    DataInQueue = new BlockingCollection<string>(); 
    var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection 
           , TaskCreationOptions.LongRunning); 

    for (int i = 0; i < 100; i++) 
    { 
    DataInQueue.Add(i.ToString()); 
    Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
         Task.CurrentId, i + " Added", 
         Thread.CurrentThread.ManagedThreadId); 
    Thread.Sleep(100); 
    } 
    ProgramEnding = true; 
} 

UPDATE:私は私がスレッドを持参DataInQueue.CompleteAddingをProgramEndingのブール値を削除し、使用することができることを見出しました終了。

答えて

18

前述のとおり、CancellationTokenを使用することができます。このようにそれを実行します。

キャンセルが要求された場合は、トークンを求めることができ、あなたの実行時間の長いタスクで
cancellationTokenSource.Cancel(); 

var cancellationTokenSource = new CancellationTokenSource(); 
Task.Factory.StartNew(RemoveFromBlockingCollection 
         , TaskCreationOptions.LongRunning 
         , cancellationTokenSource.Token); 

そして、以降のコードでは、あなたがタスクをキャンセルすることができます

if (cancellationTokenSource.Token.IsCancellationRequested) 
+0

スレッドを有効に保つためのブール値の使用か、API呼び出しがありますか?私はBlockingCollectionでCompleteAddingメソッドを使用することができますが、私はBlockingCollectionを使用していない場合、何か他のことをしていればブール値を受け取りますか? – Jon

+0

はい、うまくいくはずです。または上記のCancellationTokenを使用します。 – Fischermaen

+0

私はそれを使ってスレッドをキャンセルすることができます。 – Jon

関連する問題