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.
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 ... –
czy na barkach wypełniania reszty nie trzeba odpowiadać na odwołującego? IMO WriteRemaining powinno być w metodzie Register obiektu CancellationToken –
. 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. –