Moje pytanie brzmi: jak mogę zatrzymać długo działające zadanie (.net 4)? Wdrożyłem TPL i próbowałem używać CancellationTokenSource, ale nie działa to w moim scenariuszu. Wszystkie przykłady, które widziałem, zakładają, że wykonujesz pracę w pętli while, dzięki czemu możesz sprawdzić, czy zadanie zostało anulowane, a ja mam tylko jedną operację, która zajmuje dużo czasu. Nie mogę się doczekać ukończenia pracy, ponieważ muszę założyć, że może ona nigdy się nie zakończyć. Oto kod próbowałem:Bezpiecznie zatrzymaj długotrwałe zadanie
bool? result = null;
var cs = new CancellationTokenSource();
var ct = cs.Token;
var doWorkTask = new Task(() =>
{
Console.WriteLine("start dowork task");
result = Work.LongRunning();
}, ct);
doWorkTask.Start();
Task.WaitAny(new Task[] { doWorkTask }, timetowait);
if (doWorkTask.IsCompleted)
{
Console.WriteLine("dowork task completed");
doWorkTask.Dispose();
}
else
{
Console.WriteLine("dowork task has timedout");
cs.Cancel();
throw new TimeoutException("Timeout hit.");
}
Kod działa, ale zadanie nie jest usuwane, jeśli „timeout” dzieje i że praca jest wykonywana dostęp tj zasoby „niezarządzanego kodu”. Powiedział, że IsCancelledRequested nie może być użyty w Work.LongRunning(), więc nie mogę ThrowIfCancellationRequested.
Jestem otwarty na inne pomysły, a także próbowałem BackgroundWorker, ale to też nie wydaje się pasować.
New przykład:
var service = new System.ServiceProcess.ServiceController(ServiceName, ServerName);
var serviceTask = Task.Factory.StartNew(() =>
{
result = (service.Status == ServiceControllerStatus.Running
|| service.Status == ServiceControllerStatus.StartPending);
}, cs.Token);
serviceTask.Wait(2000, cs.Token);
if (!serviceTask.IsCompleted)
{
cs.Cancel();
}
Dzięki dla odpowiedzi! Spojrzałem na wzorzec Begin \ End, ale potem, aby sprawdzić wynik na Koniec ((Zadanie) isyncResult) .Zaznacz, że musisz poczekać, aż zakończy się. Zrobiłem aktualizację na moim przykładzie. Ponieważ właściwości kontrolera ServiceController wydają się być leniwym ładowaniem, gdy tylko sprawdzisz wartość, może to potrwać jak długo ... –
nickv
Muszę przyznać, że nie mogę całkowicie przestrzegać twojego kodu, ale dlaczego nie dodajesz kontynuacji z ContinueWith? ? – Stilgar
Ponieważ nie chcę kontynuować nowego zadania. Mam jedno zadanie, które chcę wykonać, zadanie to nie może uzyskać odpowiedzi z powodu tego, że zadanie będzie w stanie działającym na zawsze, nawet jeśli wywołano Anulowane. – nickv