背景
私は現在、およびではなく、端末インターフェイスを介して動作するGUIを使用して、何かの機能を再現しています。したがって、元のGUI形式で動作するため、エラーはイベントのトリガーとは反対側にはありません。非同期イベントによるスレッドブロックとブロック解除を管理するにはどうすればよいですか?
複数のマシンでサブタスクで構成されるタスクを実行します。
私は、進行が行われたときにトリガーとなるイベントに登録し、説明的なメッセージを出力します。 すべてのYマシンのXサブタスクごとにメッセージが出力されます。
非同期マルチスレッド処理が実行されます。
解決される各マシンのサブタスクごとに1回だけメッセージを出力したいと思います。
私はサブタスクの完了を追跡し、ローがマシンとカラムのサブタスクである2Dブール配列を維持します。
問題
デバッグするとき、私は以下のイベントハンドラメソッドが入力されていることがわかります。 numOfSubtasksFoundEventHandlerのprintステートメントが実行されますが、AutoResetイベントを設定するために到達する前に、複数のBigTaskイベントがトリガーされ、.WaitOneでブロックされます。
numOfSubtasksFound.Set()が後で実行されるにもかかわらず、何も印刷されず、プログラムが実行を終了しません。何もnumOfSubtasksFound.WaitOneを通過しません。
BigTaskHandlerメソッドのnumOfSubtasksFound.WaitOneを取り出すと、同様の動作が発生しますが、BigTaskが完了したことを示すメッセージがいくつか表示され、プログラムが別の場所で停止します。
ここでブロックとブロック解除を管理する最善の方法は何ですか?また、小さな修正はありますか?私は必要なもの
ゴール
はnumOfSubtasksFoundEventHandlerが一度実行されるまでサブタスクのイベントハンドラメソッドの動作をブロックする方法です。一度だけ実行するにはnumOfSubTasksFoundEventHandlerが必要です。
現在、サブタスクイベントハンドラは適切にアンブロックされていません。スイッチケースコードは、numOfSubtasksFound.Set()の後に決して実行されません。実行されます。
//MAIN
bool[] machinesDoneTasks = new bool[numOfMachines];
bool[][] machinesDoneSubtasks = new bool[numOfMachines][];
try
{
//thread/task blocking
numOfSubtasksFound = new AutoResetEvent(false);
AllSubTasksDone = new AutoResetEvent(false);
AllBigTasksDone = new AutoResetEvent(false);
//Subscribe to events to get number of subtasks and print useful information as tasks progress
numOfSubtasksFoundEvent += numOfSubtasksFoundEventHandler;
SubTaskProgEvent += SubTaskEventProgHandler; //prog stands for progress
BigTaskProgEvent += BigTaskProgEventHandler;
RunAllTasksOnAllMachines();//this will trigger the events above
//Don't exit program until those descriptive messages have been printed
numOfSubtasksFound.WaitOne();
AllSubTasksDone.WaitOne();
//SubTaskProgEvent -= SubTaskProgEventHandler;
AllBigTasksDone.WaitOne();
//BigTaskProgEvent -= BigTaskProgEventHandler;
}
catch (Exception e)
{
//print exceptions
}
//END MAIN
以下は必ずしもトリガーされる最初のイベントではありません。
internal void numOfSubtasksFoundEventHandler(object sender, EventArgs e)
{
//get number of subtasks from args after checking for nulls, empty arrays
for (int i = 0; i < numOfSubtasks; i++)
machinesDoneSubtasks[i] = new bool[numOfSubtasks];
Console.WriteLine("number of subtasks found");
numOfSubtasksFoundEvent -= numOfSubtasksFoundEventHandler;//don't subscribe to event where we get this from anymore
if (numOfSubtasksFound != null)
numOfSubtasksFound.Set(); //stop blocking
}
サブタスクイベントは、大きなタスクイベントの前に必ずしも処理されるとは限りません。
internal void SubtaskEventProgHandler(object sender, EventArgs e)
{
//null, empty checks on args
//Wait until we know how many subtasks there are and the 2D boolean array is fully built
numOfSubtasksFound.WaitOne();
switch (e.WhatHappened)
{
Case.TaskComplete:
Console.Write(e.Machine + " is done subtask " + e.subTask);
//logic to determine machine and subtask
machinesDoneSubtasks[machine][Subtask] = true;
if (AllSubTasksDone != null && machinesDoneSubtasks.OfType<bool>().All(x => x))
AllSubTasksDone.Set(); //stop blocking when 2D array is all true
break;
//other cases, different prints, but same idea
}
}
BigTask進捗イベントは、処理の始めと終わりに発生します。私は、私が望むケースの詳細だけを印刷します。
internal void BigTaskProgEventHandler(object sender, EventArgs e)
{
//Wait until we know how many subtasks there are and the 2D boolean array is fully built before printing
numOfSubtasksFound.WaitOne();
//null, empty exception checks
switch (e.WhatHappened)
{
Case.TaskComplete:
Console.Write(e.Machine + " is done task " + e.subTask);
//logic to determine machine
machinesDoneTasks[machine] = true;
if (AllBigTasksDone != null && machinesDoneTasks.All(x => x))
AllBigTasksDone.Set();
break;
}
//other cases, different prints, but same idea
}
.Netで非同期操作を管理する最善の方法は、async/awaitを使用することです。あなたの必要条件は何ですか?あなたが解決しようとしている問題は何ですか? – radianz
'RunAllTasksOnAllMachines'のコードを投稿できますか?また、あなたの質問を減らすことができますか?私たちは、「非同期のマルチスレッド化のシナリオが続く」というような行は必要ありません。そして、私は "非GUIインタフェースを介して"何を理解していない。と "イベントのトリガーと他の終わり。手段。あなたが書いたものをもう一度読んで理解できるかどうかを確認する必要があります。 – Enigmativity
@RobertoBastianicは、より明確になるように説明を更新しました。上記のように、私がリストしていないものはすべて正常に動作します。 質問を明確にするために質問を更新します。 – despair