複数のタスクのいずれかが失敗した場合は、再起動しようとしています。 Im HandleException(t)
メソッドがexcistingタスクの配列内のタスクを見つけ、その代わりに新しいタスクを作成する.ContinueWith(t => { HandleException(t); }, TaskContinuationOptions.OnlyOnFaulted);
を使用しています。私のHandleException(t)
メソッドに渡されたタスクだけが元のタスクと異なり、私の無駄なタスクでそれを見つけることができません。例外が処理された時点で、excistingタスクも実行されています。で 失敗したタスクの再起動
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));
}
}
マイアプリケーションの結果:
例
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
HandleException(t)
に渡されるタスクは、それがtasks[]
したがってないで発見されていない、元のタスクとは異なるので、再開されました。また、tasks[]
の状態を見ると、まだ停止していません。タスクを正しく再開するにはどうすればよいですか?
これは確かに問題でした。また、タスクのステータスも修正されました。 – MrEighteen
@Evk HandleException(t)は再帰呼び出しなので、最終的にはスタックオーバーフローが導入されませんか? –
@MaximPodkolzinいいえ、すべてが別のスレッドで発生するためです。新しいタスクは 'Task.Run'で開始され、これはスレッドプールからスレッドを取得します>例外がスローされます> HandleExceptionは別のスレッドで再度呼び出されます>' Task.Run'が再度呼び出され、別のスレッドがスレッドプールから取得されますHandleExceptionの実行中にビジー状態になっているため使用できません)>現在のスレッドは実行を終了してプールに戻ります。スタックオーバーフローの場合、同じスレッドが関数を再帰的に実行する必要がありますが、ここでは異なるスレッド(および異なるスタック)があります。 – Evk