タスクを非同期に待機する タイムアウトで完了する 質問する

タスクを非同期に待機する タイムアウトで完了する 質問する

私は待ちたいタスク<T>特別なルールで完了させる: Xミリ秒経過しても完了しない場合は、ユーザーにメッセージを表示します。Yミリ秒経過しても完了しない場合は、自動的にキャンセルをリクエストする

使うことができますタスクの続行タスクが完了するまで非同期に待機する(つまり、タスクが完了したときに実行されるアクションをスケジュールする)が、タイムアウトを指定することはできません。タスク.待機タスクがタイムアウトで完了するのを同期的に待機しようとしましたが、スレッドがブロックされてしまいます。タスクがタイムアウトで完了するのを非同期的に待機するにはどうすればよいでしょうか?

ベストアンサー1

これはどう:

int timeout = 1000;
var task = SomeOperationAsync();
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
    // task completed within timeout
} else { 
    // timeout logic
}

そしてここにこの種のことについての詳しい情報は、素晴らしいブログ記事「Task.TimeoutAfter メソッドの作成」(MS Parallel Library チームによる) をご覧ください。

追加: 私の回答に対するコメントのリクエストに応じて、キャンセル処理を含む拡張ソリューションを示します。タスクとタイマーにキャンセルを渡すと、コード内でキャンセルが発生する方法が複数あるため、必ずテストして、すべてを適切に処理できることを確認する必要があります。さまざまな組み合わせを偶然に任せて、コンピューターが実行時に正しい処理を実行することを期待しないでください。

int timeout = 1000;
var task = SomeOperationAsync(cancellationToken);
if (await Task.WhenAny(task, Task.Delay(timeout, cancellationToken)) == task)
{
    // Task completed within timeout.
    // Consider that the task may have faulted or been canceled.
    // We re-await the task so that any exceptions/cancellation is rethrown.
    await task;

}
else
{
    // timeout/cancellation logic
}

おすすめ記事