-
Notifications
You must be signed in to change notification settings - Fork 0
Work Control
Pause(...)
スレッドプールまたはタスクを一時停止します。引数として work id(s)
を使用できます。
Resume(...)
スレッドプールまたはタスクを再開します。引数として work id(s)
を使用できます。
Stop(...)
スレッドプールまたはタスクを停止します。引数として work id(s)
と 強制停止フラグ
を使用できます。
Wait[Async](...)
スレッドプールまたはタスクの完了を待機します。引数として work id(s)
を使用できます。
Fetch[Async](...)
タスクの結果を取得します。引数として work id(s)
、述語関数
、および 取得後に結果をストレージから削除するフラグ
を使用できます。
Cancel(...)
まだ開始されていないタスクをキャンセルします。引数として work id(s)
を使用できます。
PauseIfRequested()
タスクロジック内に一時停止ポイントを挿入します。
StopIfRequested(...)
タスクロジック内に停止ポイントを挿入します。引数として 停止処理前に実行する関数
を使用できます。
CheckIfRequestedStop()
タスクロジック内にチェックポイントを挿入し、Stop(...)
が呼び出されたかを確認します。
PowerPool powerPool = new PowerPool();
string id0 = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
if (powerPool.CheckIfRequestedStop())
{
return true;
}
// 何かを実行
}
});
Task<ExecuteResult<bool>> resultTask = powerPool.FetchAsync<bool>(id0);
powerPool.Pause();
powerPool.Resume();
powerPool.Stop();
powerPool.Wait();
ExecuteResult<bool> result = await resultTask;
string id1 = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
powerPool.StopIfRequested();
// 何かを実行
}
});
powerPool.Pause(id1);
powerPool.Resume(id1);
powerPool.Stop(id1);
powerPool.Wait(id1);
Thread.Abort
、Thread.Suspend
、Thread.Resume
は予測不可能な動作を引き起こす可能性があり、新しい .NET バージョンでは非推奨になっています。そのため、PowerThreadPool ライブラリではこれらの API を使用してスレッドを制御しません。
PowerThreadPool は CancellationTokenSource
と ManualResetEvent
の操作をカプセル化し、協調的なスレッドプールとタスク制御を提供します。
タスクロジック内で PauseIfRequested()
、StopIfRequested(...)
、または CheckIfRequestedStop()
(例えば、ループや時間のかかるロジックのノード内)を挿入して、実行フローを管理できます。Pause
、Resume
、または Stop
関数を呼び出すと、ロジックが予期した位置で一時停止、再開、または停止します。これらの関数の引数としてタスク ID を使用することで、他のタスクが影響を受けないようにできます。
-
PauseIfRequested():タスクロジック内でこの関数を呼び出すと、
Pause(...)
が呼び出されたときにタスクがその場で一時停止します。 -
StopIfRequested(Func<bool> beforeStop = null):タスクロジック内でこの関数を呼び出すと、
Stop(...)
が呼び出されたときにタスクがその場で停止します。
ロジックを終了するために、この関数はPowerThreadPool.Exceptions.WorkStopException
をスローします。WorkStopException
はタスクを停止するためだけに使用されるため、これをキャッチしないでください。PowerThreadPool が自動的に処理します。
停止前にいくつかの操作(例えば、非管理リソースの解放)を実行したい場合、または特定の条件下で停止を防ぎたい場合は、引数beforeStop
を使用することをお勧めします。
この方法でロジックを終了したくない場合は、CheckIfRequestedStop
を使用することもできます。 -
CheckIfRequestedStop():タスクロジック内でこの関数を呼び出して、
Stop(...)
が呼び出されたかどうかを確認します。
true
を返す場合、いくつかの前処理操作(例えば、非管理リソースの解放)を実行した後、安全にロジックを終了できます。状況に応じて、停止要求を無視することも選択できます。
この方法でタスクを停止すると、WorkStopped
イベントはトリガーされず、タスクが正常に完了したと見なされます。
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
powerPool.StopIfRequested();
// 何かを実行
}
});
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
powerPool.PauseIfRequested();
powerPool.StopIfRequested(() =>
{
// return 前に何かを実行
if (/* 停止を続けたい場合 */)
{
return true;
}
else
{
return false;
}
});
// 何かを実行
}
});
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
if (powerPool.CheckIfRequestedStop())
{
// return 前に何かを実行
return;
}
// 何かを実行
}
});
powerPool.Pause();
powerPool.Pause(workID);
powerPool.Pause(workIDList);
powerPool.Resume();
powerPool.Resume(workID);
powerPool.Resume(workIDList);
powerPool.Stop();
powerPool.Stop(workID);
powerPool.Stop(workIDList);
Stop
関数がブール引数(つまり forceStop
)を true
として受け取る場合、タスクロジック内に StopIfRequested(...)
が挿入されていなくてもスレッドを停止できます。これは Thread.Interrupt()
が呼び出されるためです。スレッドプールは ThreadInterruptedException
をキャッチした後、スレッドを即座に終了します。
この方法は Thread.Abort
よりも安全ですが、ビジネスロジックの観点からすると予測不可能な結果を引き起こす可能性があり、スレッドを終了するのに必要な時間を保証できません。そのため、強制停止は可能な限り避けるべきです。
この方法で停止したスレッドは破棄され、再利用されません。
string workID = powerPool.QueueWorkItem(() =>
{
while (true)
{
// 何かを実行
}
});
powerPool.Stop(true);
powerPool.Stop(workID, true);
powerPool.Stop(workIDList, true);
呼び出しスレッドは、すべてのタスクが終了するまでブロックされます。
タスク ID を Wait の引数として使用することで、他のタスクが影響を受けないようにできます。
Wait
の非同期バージョンは WaitAsync
です。
powerPool.Wait();
powerPool.Wait(workID);
powerPool.Wait(workIDList);
Fetch
関数はタスクの結果を取得するために使用されます。呼び出し後、タスクが完了次第 ExecuteResult を返します。
workID
または workIDList
を引数として指定します。
通常、Fetch
関数はまだ開始されていない、または進行中のタスクの結果を取得するために使用されます。
この関数はブロッキング動作であり、指定されたタスクが完了して結果を返すまで、呼び出しスレッドの実行を一時停止します。
非ブロッキング動作を希望する場合は、FetchAsync
関数を使用できます。この関数はタスクの結果を非同期で取得し、呼び出しスレッドの実行を中断しません。
引数として 述語関数
を指定します。
述語関数を使用して、既存の結果から一致する結果セットを検索します。述語関数は、ExecuteResult<TResult>
を引数として受け取り bool
値を返す関数であり、LINQ の Where
に似ています。
既存の結果からフィルタリングするため、ブロッキングを引き起こさず、非同期バージョンはありません。
Fetch
の非同期バージョンは FetchAsync
です。
powerPool.Fetch(workID);
powerPool.Fetch(workIDList);
powerPool.Fetch<int>(x => x.Result >= 3);
デフォルトでは、メモリオーバーフローを防ぐために、スレッドプールはタスクの実行結果を保存しません。完了したタスクの結果を保持したい場合は、WorkOption.ShouldStoreResult
を true
に設定してください。これにより、タスクが完了した後に結果を保存するようスレッドプールに指示されます。
保存された実行結果をクリアする方法は以下の 3 つです:
-
PowerPoolOption.ClearResultStorageWhenPoolStart
をtrue
に設定します。この設定により、スレッドプールが再実行状態に入るときに保存された実行結果がクリアされます。
PowerPool powerPool = new PowerPool(new PowerPoolOption() { ClearResultStorageWhenPoolStart = true });
-
Fetch
関数のオプション引数をtrue
に設定します(Fetch(workID, true)
など)。これにより、Fetch
を呼び出したときにタスク ID に対応する実行結果がクリアされます。
powerPool.Fetch(workID, true);
powerPool.Fetch(workIDList, true);
-
PowerPool.ClearResultStorage(...)
を直接呼び出します。
powerPool.ClearResultStorage();
powerPool.ClearResultStorage(workID);
powerPool.ClearResultStorage(workIDList);
Cancel
関数は、まだ開始されていないタスクをキャンセルするために使用されます。
タスク ID を Cancel の引数として使用することで、他のタスクが影響を受けないようにできます。
powerPool.Cancel();
powerPool.Cancel(workID);
powerPool.Cancel(workIDList);