Ich versuche, eine von mehreren Aufgaben neu zu starten, wenn es fehlschlägt. Ich benutze .ContinueWith(t => { HandleException(t); }, TaskContinuationOptions.OnlyOnFaulted);
wo die HandleException(t)
Methode sollte die Aufgabe in dem Array von bestehenden Aufgaben und erstellen Sie eine neue an ihrer Stelle. Nur die Aufgabe, die an meine HandleException(t)
-Methode übergeben wurde, unterscheidet sich von der ursprünglichen Aufgabe, so dass ich sie in meinen bestehenden Aufgaben nicht finden kann. Auch die bestehende Aufgabe läuft zum Zeitpunkt der Ausnahme noch.Neustarten Aufgabe, wenn es
Beispiel:
using System;
using System.Threading.Tasks;
using System.Threading;
static Task[] tasks;
static void Main(string[] args)
{
tasks = new Task[2];
for (int i = 0; i < tasks.Count(); i++)
{
tasks[i] = Task.Run(() => { Thread.Sleep(1000); throw new Exception("BOOM"); })
.ContinueWith(t => { HandleException(t); }
, TaskContinuationOptions.OnlyOnFaulted);
Console.WriteLine(String.Format("Task {0} started", tasks[i].Id));
}
Console.ReadLine();
}
static void HandleException(Task task)
{
Console.WriteLine(String.Format("Task {0} stopped", task.Id));
// Check task status
for (int i = 0; i < tasks.Count(); i++)
{
Console.WriteLine(String.Format("Task {0} status = {1}", i, tasks[i].Status));
}
// fFind and restart the task here
if (tasks.Contains(task))
{
int index = Array.IndexOf(tasks, task);
tasks[index] = Task.Run(() => { Thread.Sleep(1000); throw new Exception("BOOM"); })
.ContinueWith(t => { HandleException(t); }
, TaskContinuationOptions.OnlyOnFaulted);
Console.WriteLine(String.Format("Task {0} started", tasks[index].Id));
}
}
Meine Anwendung ergibt:
Task 3 started
Task 6 started
Task 5 stopped
Task 0 status = Running
Task 2 stopped
Task 1 status = Running
Task 0 status = Running
Task 1 status = Running
Da die an die HandleException(t)
weitergegeben Aufgabe von der ursprünglichen Aufgabe unterschiedlich ist, wird es nicht in den tasks[]
gefunden und somit nicht neu gestartet. Betrachtet man auch die Zustände der tasks[]
ist es noch nicht gestoppt. Wie kann ich meine Aufgabe ordnungsgemäß neu starten?
Ehrfürchtig, das war in der Tat das Problem. Es hat auch den Aufgabenstatus behoben. – MrEighteen
@Evk Da HandleException (t) ein rekursiver Aufruf ist, führt das nicht zu einem Stack-Überlauf? –
@MaximPodkolzin nein, weil alles auf verschiedenen Threads passiert. Neue Aufgabe wird über 'Task.Run' gestartet, dies ruft einen Thread aus dem Thread-Pool ab> Ausnahme wird ausgelöst> HandleException wird aufgerufen, möglicherweise erneut in einem anderen Thread>' Task.Run' wird erneut aufgerufen und ein anderer Thread wird aus dem Thread-Pool abgerufen (das selbe kann nicht verwendet werden, da es mit der Ausführung von HandleException beschäftigt ist.> Der aktuelle Thread beendet die Ausführung und kehrt zum Pool zurück. Für einen Stack-Überlauf sollte derselbe Thread die Funktion rekursiv ausführen, aber hier haben wir verschiedene Threads (und damit verschiedene Stacks). – Evk