2011-11-16 25 views
8

Powiedzmy, że mam procesor, którego zadaniem jest utrwalanie plików z powrotem na dysk. Działa to jako Task podczas obserwacji pliku BlockingCollection<T> dla plików do przetworzenia.Najlepsze praktyki anulowania zadań:

Kiedy zadanie zostanie anulowane i nadal istnieją pliki, które powinny zostać zapisane na dysku, co byłoby dobrym rozwiązaniem, aby to zrobić?

Dobrze byłoby, aby zadanie tuż przed wyjściem szybko zapisało pliki pozostające z powrotem na dysku, chociaż nie jestem pewien, czy jest to sprzeczne z filozofią anulowania zadania (ponieważ anulowanie powinno nastąpić tak szybko, jak to możliwe) .

Inną opcją jest wykonanie drugiej procedury po anulowaniu zadania, którego zadaniem jest zapisanie pozostałych plików na dysku. Przykładem

Kod:

class FileProcessor 
{ 
    private readonly BlockingCollection<Stream> input; 

    public FileProcessor(BlockingCollection<Stream> input) 
    { 
     _input = input; 
    } 

    public Task Run(CancellationToken cancellationToken, 
     BlockingCollection<Stream> input) 
    { 
     return Task.Factory.StartNew(() => 
     { 
      foreach (Stream stream in 
         input.GetConsumingEnumerable(cancellationToken)) 
      { 
       WriteToDisk(stream); 
      } 

      // Should I call WriteRemaining here or should I have 
        // a process running after this task exited which 
        // will call WriteRemaining 
      WriteRemaining(); 
     }); 
    } 

    public void WriteRemaining() 
    { 
     foreach (Stream stream in input)  
     { 
      WriteToDisk(stream); 
     } 
    } 
} 

Wiem, że to trochę otwartym pytaniem, aplikacja/wymagania/ilość plików napisać również odgrywać pewną rolę, ale ja szukam dla ogólnej wytycznej/najlepszy praktyki tutaj.

+0

Nie sądzę, że naprawdę chcesz "anulować" w tym przypadku, myślę, że po prostu chcesz przerwać przetwarzanie, które można łatwo wykonać za pomocą prostego semafora na dowolnym początku. Aby powiedzieć "Anuluj", oznacza natychmiastowe zatrzymanie się na coś innego, jeśli chcesz mieć bezpieczny "Stop", możesz to zrobić poza potencjalnym anulowaniem. Ale nie jestem pewien, czy to jest najlepsza praktyka ... –

+0

czy na barkach wypełniania reszty nie trzeba odpowiadać na odwołującego? IMO WriteRemaining powinno być w metodzie Register obiektu CancellationToken –

+0

. Nie ma żadnego zobowiązania umownego do anulowania, aby spowodować szybkie zakończenie lub nawet spowodować anulowanie. Jeśli Twój proces nie obsługuje anulowania, możesz zignorować Anuluj i po prostu zakończyć pomyślnie. –

Odpowiedz

9

Cancellation is a cooperative action podczas pracy z biblioteką zadań i tak, zalecana jest szybka operacja anulowania.

Pamiętaj, że jest to anulowanie, a nie anulowanie i oczyszczenie. Jeśli masz dodatkowe operacje, które musisz wykonać w wyniku anulowania, operacje te powinny nastąpić poza oryginalnym zadaniem, które zostało anulowane.

Należy pamiętać, że to nie powstrzyma cię od nazywając ContinueWith i wykonywania operacji w nowyTask który sprawdza, czy IsCanceled property powraca true a następnie wykonuje oczyszczanie oparte na tym.

Najważniejsze jest to, że nie chcesz blokować oryginalnej wersji Task, która została anulowana, ale możesz rozpocząć nową instalację, aby wykonać wszelkie operacje czyszczenia, które musisz wykonać w wyniku anulowania.