Запускает ли Task.Wait(int) задачу, если тайм-аут истекает без завершения задачи?
У меня есть задача, и я ожидаю, что она займет меньше секунды, но если это займет больше нескольких секунд, я хочу отменить задачу.
Например:
Task t = new Task(() =>
{
while (true)
{
Thread.Sleep(500);
}
});
t.Start();
t.Wait(3000);
Обратите внимание, что после 3000 миллисекунд срок ожидания истекает. Было ли задание отменено, когда истечение тайм-аута истекло, или задача все еще запущена?
Ответы
Ответ 1
Если вы хотите отменить 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
.
Ответ 2
Task.Wait()
ждет до указанного периода завершения задачи и возвращает, завершилась ли задание в указанный промежуток времени (или раньше) или нет. Сама задача не изменяется и не полагается на ожидание.
Прочитайте прекрасную серию: Parallelism в .NET, Parallelism в .NET - Часть 10, Отмена в PLINQ и Параллельный класс от Рида Копси
И: .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();
Ответ 3
Задача по-прежнему выполняется до тех пор, пока вы явно не остановите ее или не закончите цикл (что никогда не произойдет).
Вы можете проверить возвращаемое значение Wait, чтобы увидеть это:
(из http://msdn.microsoft.com/en-us/library/dd235606.aspx)
Возвращаемое значение
Тип: System.Boolean
true, если Задача завершила выполнение в течение отведенного времени; в противном случае - false.
Ответ 4
Было ли отменено задание, когда истечение тайм-аута истекло ли выполнение задачи?
Нет и Да.
Таймаут, прошедший до Task.Wait
, относится к Wait
, а не к задаче.