0

簡単なことをしたい(それContinueWithスレッドセーフであると仮定して):

readonly Task _task = Task.CompletedTask;

// thread A: conditionally prolong the task
if(condition)
    _task.ContinueWith(o => ...);

// thread B: await for everything
await _task;

問題: 上記のコードでは、すぐに戻り、内部タスクawait _taskがあるかどうかを無視します。

複数回_task延長できる要件を拡張していますが、それらすべてが終了するのをどのように待ちますか? ContinueWith


もちろん、私は古いスレッドセーフな方法でそれを試みることができます:

Task _task = Task.CompletedTask;
readonly object _lock = new object();

// thread A
if(condition)
    _lock(_lock)
        _task = _task.ContinueWith(o => ...); // storing the latest inner task

// thread B
lock(_lock)
    await _task;

または、タスクをスレッドセーフ コレクションに格納し、Task.WaitAll.

しかし、最初のスニペットを簡単に修正できるかどうか知りたいです。

4

2 に答える 2

-1

元のコードでは完了しているawait _task;ため、すぐに戻ります。taskあなたがする必要があります

_task = _task.ContinueWith(...);

ロックを使用する必要はありません。あなたは同じスレッドで作業しています。コードの「ロック」バージョンでは_task = _task.ContinueWith(...)、ロックのためではなく、それが機能する理由です。


編集: _task = _task.ContinueWith(...);1 つのスレッドと_task = _task.ContinueWith(...).

これは設計としてかなり悪いです。スレッドとタスクを組み合わせてはいけません。タスクのみのソリューションか、スレッドのみのソリューションを選択する必要があります。

タスクのみのソリューション (推奨) を選択する場合は、適切な一連の作業タスクを作成し、各タスクで前のタスクの結果に基づいて続行する方法を決定します。

スレッドのみのソリューションを使用する場合ManualResetEventは、ハンドルを使用してタスクを同期することをお勧めします。

于 2019-11-18T10:22:27.807 に答える