5

さまざまなファイルから読み取り、単語を見つけるというさまざまなタスクがあります。次のように、waitAny メソッドで開始するタスク配列にそれらを入れました。

foreach (string file in filesList)
        {
            files[i] = Task.Factory.StartNew(() =>
            {
                mySearch.Invoke(file);
            });
            i++;
        }
        System.Threading.Tasks.Task.WaitAny(files);

タスクの1つが終了したらすぐに他のすべてのタスクを停止したいと思います(単語が見つかったときに終了します)。今のところ、waitany を使用すると、1 つのタスクがいつ終了するかを知ることができますが、どのタスクが終了したか、および他のタスクを停止する方法を知る方法がわかりません。これを達成するための最良の方法は何ですか?

4

3 に答える 3

2

CancellationTokenすべてのタスクが共有するシングルを使用できます。タスクをキャンセルするための内部mySearch.Invokeメソッド検証値。token.IsCancellationRequested一部のタスクが終了したら、他のタスクをキャンセルしCancellationTokenSource.Cancel()ます。

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token; 

foreach (string file in filesList)
{
   // pass cancellation token to your task
   files[i] = Task.Factory.StartNew(() => mySearch.Invoke(file, token), token);
   i++;
}

Task.WaitAny(files);
tokenSource.Cancel();

ところでOperationCanceledException、呼び出しによってソースがキャンセルされたときにトークンを強制的にスローできますtoken.ThrowIfCancellationRequested()

于 2012-11-29T16:07:54.943 に答える
2

Task を作成するときに、CancelationTokenを渡すことができます。タスクの 1 つが終了したら、このトークンを設定します。これにより、このトークンを持つ残りのタスクが実行されなくなります。実行中のタスクは、受信しOperationCanceledExceptionて停止することもできます。

于 2012-11-29T16:08:17.277 に答える
1

キャンセルできない非同期操作をキャンセルするにはどうすればよいですか? を読むことを強くお勧めします。スティーブン・トゥーブ著。基本的に、これらのタスクをすべてキャンセルする必要がありますが、現在、それらをキャンセルするメカニズムはありません。

理想的なアプローチはCancellationTokenSource、 foreach の前にを作成しCancellationToken、そのソースから各子タスクに を渡し、そのトークンを定期的にチェックし、キャンセルが示されていることに気付いたら作業を停止することです。WhenAnyその後、継続でトークン ソースをキャンセルできます。

それができない場合は、タスクを実際に停止することが重要なのか (これは実際には実行できません)、それとも終了するのを待たずにコードを続行する必要があるのか​​ (それは簡単です) を決定する必要があります。する)。

于 2012-11-29T16:09:49.443 に答える