Время ожидания задачи с использованием ожидания в .NET 4.5

Я пробую Async/Await в VB.NET 4.5 и хотел бы, чтобы моя задача прервалась, если она не завершается в течение определенного периода. у меня есть

Await Task.Run( Sub() PerformSomeAction() )

что вроде аккуратно. Я также вижу, что существует форма Task.Run, которая принимает токен отмены. Как я могу использовать это, чтобы отменить задачу в случае тайм-аута?

ИЗМЕНИТЬ

У меня есть следующее прототипное решение

    Dim cts = New CancellationTokenSource()
    Dim ct As CancellationToken = cts.Token
    Dim delay = Task.Delay(1000)
    Dim completed = Await Task.WhenAny(Task.Run(Sub() PerfomSomeAction(ct), ct), delay)
    If completed Is delay Then
            cts.Cancel()
    End If

Это выглядит довольно шумным кодом. Это хорошо? Другой идеей было бы обрабатывать тайм-аут как исключение и использовать cts.CancelAfter. Что-то вроде этого??

    Dim cts = New CancellationTokenSource()
    Dim ct As CancellationToken = cts.Token
    try
        cts.CancelAfter(1000) 'ms
        Dim completed = Task.Run(Sub() PerformSomeAction(ct), ct)
    catch SomeTimeoutException
    end try

и с помощью PerformSomeAction я выбрасываю SomeTimeoutException, если получаю обнаружение маркера отмены.


person bradgonesurfing    schedule 14.09.2012    source источник
comment
Вы должны использовать подход CancelAfter в дополнение к ThrowIfCancellationRequested, как ответил svick.   -  person Stephen Cleary    schedule 14.09.2012


Ответы (1)


Tasks поддерживают совместную отмену, это означает, что если вы хотите отменить уже запущенный Task, код внутри Task должен поддерживать отмену, и он решает, когда он будет отменен. Этого можно добиться, передав методу токен отмены и вызвав ThrowIfCancellationRequested() в соответствующих местах кода этого метода.

Если код в Task не поддерживает отмену, нет простого способа отменить или прервать его.

person svick    schedule 14.09.2012
comment
И как аккуратно обнаружить в коде продолжения, что произошел тайм-аут или произошло правильное поведение. Я привел два примера: исключение тайм-аута или проверку результата. Существует ли общепринятый шаблон для поддержания потока кода в чистоте? - person bradgonesurfing; 14.09.2012
comment
Да, если вы правильно отмените Task, а затем await, он выдаст TaskCancelledException. - person svick; 14.09.2012