Sicher anhalten long running task
Meine Frage ist, wie kann ich verhindern, dass eine lang laufende task (.net 4)? Ich habe umgesetzt TPL und versucht, mit dem CancellationTokenSource, aber es scheint nicht zu funktionieren für mein Szenario. Alle Beispiele, die ich gesehen habe davon aus, dass Sie die Arbeit in einer while-Schleife, so dass Sie überprüfen können, ob die Aufgabe wurde abgebrochen, während ich nur eine einzige operation, die dauert lange. Ich kann nicht warten, bis die arbeiten abgeschlossen werden, da muss ich annehmen, dass es vielleicht nie abgeschlossen.
Hier ist der code, den ich versucht habe:
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.");
}
Der code funktioniert, aber die Aufgabe ist nie freigegeben, wenn die "timeout" passiert, und die Arbeit, die getan wird, greift auf "unmanaged code", d.h. Ressourcen. Das sagte die IsCancelledRequested nicht verwendet werden kann, in Arbeit.LongRunning (), so kann ich nicht ThrowIfCancellationRequested.
Ich bin offen für andere Ideen, so gut wie ich haben versucht, BackgroundWorker, aber auch dass scheint nicht zu passen.
Neues Beispiel:
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();
}
InformationsquelleAutor nickv | 2012-05-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist ein Beispiel für option 1 beschrieben teleologische ( D. H. nur die Tötung der Aufgabe ohne Signalisierung Stornierung)
InformationsquelleAutor Avi Ben-Margi
Task Parallel Library ist ausgelegt für CPU-intensive Arbeit. CPU-intensive Arbeit wird in einer Weile sehen. Wenn Ihre Arbeit.LongRunning() ist CPU-intensiv, Sie sollten in der Lage sein, um übergeben Sie die Kündigung token innen und stornieren. Wenn es nicht CPU-intensiv, dann können Sie einfach entsorgen Sie das Ergebnis in einem eventuellen Rückruf und nicht die Mühe mit dem beenden der eigentlichen Arbeit, da ist es einfach nur warten.
BTW, wenn Sie warten (für Datenbank-Aufruf oder so) vermutlich haben Sie asynchrone Methoden irgendwo an der Unterseite. Sie können die Oberfläche der Begin/End-Muster und wickeln Sie es in eine Aufgabe. Diese Frage erklärt, wie: TPL TaskFactory.FromAsync vs Aufgaben mit blocking-Methoden Diese Weise vermeiden Sie überhöhung ein allgemeiner thread, da IO warten geschieht in besonderer Weise behandelt, indem das OS.
Ich muss zugeben, dass ich nicht verfolgen können, Ihren code komplett, aber warum bist du nicht hinzufügen Fortsetzungen mit ContinueWith?
Weil ich möchte nicht weiter mit einer neuen Aufgabe. Ich habe eine Aufgabe, ich möchte ausführen, dass die Aufgabe nicht hield eine Reaktion aufgrund von was auch immer, so wird die task in den Status " wird ausgeführt für immer obwohl Storniert wurde genannt.
Sie brauchen nichts zu tun, wenn die Aufgabe erfolgreich abgeschlossen? Wenn Sie das tun, dann müssen Sie weiterhin mit einer anderen Aufgabe. Wenn Sie nicht dann tun Sie nichts (da die Aufgabe ist nicht CPU-intensiv).
InformationsquelleAutor Stilgar