2011-10-27 16 views
21

Czy jest to dobry projekt dla wątku tła, który musi zostać uruchomiony przy użyciu interfejsu API Task w .Net 4? Moją jedyną troską jest to, czy chcemy anulować to zadanie, jak bym to zrobił? Wiem, że mogę ustawić ProgramEnding na true, ale wiem, że w interfejsie API zadań jest CancellationToken.Najlepsza praktyka LongRunning Tworzenie zadań

To tylko przykładowa próbka kodu, aby jeden wątek był dodawany do kolekcji, a inny wątek będzie z niego usuwany. Zadanie jest ustawiony jako LongRunning jak to musi być uruchomiony w sposób ciągły, podczas gdy program jest uruchomiony

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: Odkryłem, że mogę usunąć logiczną ProgramEnding i używać DataInQueue.CompleteAdding które który przynieść wątku koniec.

Odpowiedz

18

Jak już wspomniano, można użyć Znacznika Anulowania. Zrobić to w ten sposób:

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

a później w kodzie, można anulować zadanie z:

cancellationTokenSource.Cancel(); 

W swojej długiej zadania uruchomionego można poprosić token, jeśli odwołanie została wezwana:

if (cancellationTokenSource.Token.IsCancellationRequested) 
+0

Czy użycie wartości boolowskiej ma na celu sprawdzenie, czy wątek jest najlepszą praktyką lub czy istnieje wywołanie interfejsu API? Zauważyłem, że mogę użyć metody CompleteAdding w BlockingCollection, ale jeśli nie używam BlockingCollection i robię coś innego, to czy boolean będzie dostępny? – Jon

+0

Tak, to by działało. Możesz też użyć Tokenu Anulowania, o którym wspomniałem powyżej. – Fischermaen

+0

Mogę użyć tego, aby anulować wątek, który właśnie pytałem twoją opinię, aby wątek działał? – Jon

Powiązane problemy