web-dev-qa-db-ja.com

タスクが終了せずにタイムアウトが経過すると、Task.Wait(int)はタスクを停止しますか?

タスクがあり、実行に1秒未満かかると予想していますが、数秒以上かかる場合はタスクをキャンセルします。

例えば:

Task t = new Task(() =>
        {
            while (true)
            {
                Thread.Sleep(500);
            }
        });
t.Start();
t.Wait(3000);

3000ミリ秒後に待機が期限切れになることに注意してください。タイムアウトの期限が切れたときにタスクはキャンセルされましたか、それともタスクはまだ実行中ですか?

31
Paul Mendoza

Taskをキャンセルする場合は、タスクを作成するときにCancellationTokenを渡す必要があります。これにより、外部からTaskをキャンセルできます。必要に応じて、キャンセルをタイマーに関連付けることができます。

キャンセルトークンを使用してタスクを作成するには、次の例を参照してください。

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

var t = Task.Factory.StartNew(() => {
    // do some work
    if (token.IsCancellationRequested) {
        // Clean up as needed here ....
    }
    token.ThrowIfCancellationRequested();
}, token);
_

Taskをキャンセルするには、tokenSourceCancel()を呼び出します。

16
Brian Rasmussen

Task.Wait()は、タスクの完了を指定された期間まで待機し、指定された時間(またはそれ以前)にタスクが完了したかどうかを返します。タスク自体は変更されず、待機に依存しません。

ニースシリーズを読む: 。NETでの平行度。NETでの平行度–パート10、PLINQおよびParallelクラスでのキャンセル by Reed Copsey

そして: 。NET 4 Cancellation Framework / パラレルプログラミング:タスクキャンセル

次のコードを確認してください。

var cts = new CancellationTokenSource();

var newTask = Task.Factory.StartNew(state =>
                           {
                              var token = (CancellationToken)state;
                              while (!token.IsCancellationRequested)
                              {
                              }
                              token.ThrowIfCancellationRequested();
                           }, cts.Token, cts.Token);


if (!newTask.Wait(3000, cts.Token)) cts.Cancel();
52

タスクは、明示的に停止するよう指示するか、ループが終了するまで実行されます(これは決して発生しません)。

Waitの戻り値を確認して、これを確認できます。

(from http://msdn.Microsoft.com/en-us/library/dd235606.aspx )戻り値

型:System.Booleanタスクが割り当てられた時間内に実行を完了した場合はtrue。それ以外の場合はfalse。

7
vdoogs

タイムアウトの期限が切れたときにタスクはキャンセルされましたか、それともタスクはまだ実行中ですか?

いいえ、はい。

Task.Waitに渡されるタイムアウトは、タスクではなくWait用です。

6
Richard