Останавливает ли Task.Wait (int) задачу, если время истекло без завершения задачи? - PullRequest
30 голосов
/ 27 октября 2010

У меня есть задача, и я ожидаю, что ее выполнение займет менее секунды, но если это займет больше нескольких секунд, я хочу отменить задачу.

Например:

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

Обратите внимание, что через 3000 миллисекунд ожидание истекает. Была ли задача отменена по истечении времени ожидания или она все еще выполняется?

Ответы [ 4 ]

52 голосов
/ 27 октября 2010

Task.Wait() ждет до указанного периода для завершения задачи и возвращает, была ли задача завершена в указанный промежуток времени (или ранее) или нет. Само задание не изменяется и не зависит от ожидания.

Прочитайте хорошую серию: Параллелизм в .NET , Параллелизм в .NET - Часть 10, Отмена в PLINQ и классе Parallel Ридом Копси

И: .NET 4 Framework 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();
15 голосов
/ 27 октября 2010

Если вы хотите отменить 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, позвоните Cancel() на tokenSource.

7 голосов
/ 27 октября 2010

Задача все еще выполняется, пока вы явно не скажете ей остановиться или цикл завершится (что никогда не произойдет).

Вы можете проверить возвращаемое значение Wait, чтобы увидеть это:

(из http://msdn.microsoft.com/en-us/library/dd235606.aspx) Возвращаемое значение

Тип: System.Boolean истина, если Задача завершила выполнение в течение отведенного времени; в противном случае - ложь.

6 голосов
/ 27 октября 2010

Была ли задача отменена по истечении времени ожидания или она еще выполняется?

Нет и Да.

Время ожидания, переданное Task.Wait, относится к Wait, а не к задаче.

...