TPLとタスクについてサポートが必要です
これが私のシナリオです:
タスクを生成するイベントハンドラーがいくつかあります。前のタスクが完了する前にイベントが呼び出された場合、続行する前にイベントを待機(ブロック)したいと思います。
呼び出されたときに、イベントハンドラーから生成されたタスクが完了するまで待機してから続行する必要がある同期メソッドがあります。
public void DoSomething()
{
// Expects any running tasks from OnEvent1(), OnEvent2(), OnEvent3()
// to be completed before proceeding.
}
public void OnEvent1()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent2()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent3()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
実際のシナリオは次のようになります。
- OnFetchData() =>タスクを生成します。これに対する後続のすべての呼び出しは、キューに入れる必要があります。
OnSyncSettings() =>タスクを生成します。これに対する後続のすべての呼び出しは、キューに入れる必要があります。
OnAutoBackup() =>同期メソッド。保存する前に、他のタスク(たとえば、データのフェッチ/同期設定)が完了するのを待ちます。
- OnFullBackup() =>同期メソッド。FetchData()とSyncSettings()を手動で実行し、完了を待って続行します。
私の質問は単純です:どうすればこれを行うことができますか?
このアプローチは正しいでしょうか?
各イベントハンドラーは最後のを記憶しています。呼び出されると、リスト内のすべてのタスクが完了するのを待ってから続行します。
同期方式の場合、すべてのタスク(すべてのイベントハンドラーから)を待機する必要があります。
Task _lastEvent1Task;
public void OnEvent1()
{
// Wait for all tasks to complete before proceeding
if (_lastEvent1Task!=null)
_lastEvent1Task.Clear();
// Spawns new task
_lastEvent1Task = Task.Factory.StartNew(()=>{ });
}
public void OnEvent3()
{
// Wait for any running tasks to complete before proceeding
if (_lastEvent1Task != null) _lastEvent1Task.Wait();
if (_lastEvent2Task != null) _lastEvent2Task.Wait();
...
// Proceed
}
ありがとう!
[編集]
DoSomething()が待機していて、Event1が発生した場合はどうなりますか?DoSomething()が実行されていて、イベントが発生した場合はどうなりますか?
OnEvents()
- 最初のタスクの場合:タスクを生成し、非同期で実行します
- 前のタスクがまだ実行中の場合は、キュー/ブロックします。クリティカルセクション。
- 推定:
- これらのイベントは通常、複数回発生することはありません。
- UIは、ユーザーが実行中に同じイベントを発生させないようにすることが期待されています。
DoSomething()(呼び出された場合)
- 想定:イベント通知は無効になっています。
- 仮定:新しいイベントはキューに入れられません。
- 予想:続行する前に、キューに入れられた残りのすべてのタスクが完了するまで待機します
- 期待される:同期呼び出しであり、実行されるまで呼び出し元に戻らない