0

когда придет Task.IsCanceled = true;, когда Task.IsCancelled настроен как истинный?

Код:

  var cts = new CancellationTokenSource(); 
      string result = ""; 
      cts.CancelAfter(10000); 
      try 
      { 
       Task t = Task.Run(() => 
       { 
        using (var stream = new WebClient().OpenRead("http://www.rediffmail.com")) 
        { 
         result = "success!"; 
        } 
        cts.Token.ThrowIfCancellationRequested(); 
       }, cts.Token); 

       Stopwatch timer = new Stopwatch(); 
       timer.Start(); 
       while (timer.IsRunning) 
       { 
        if (timer.ElapsedMilliseconds <= 10000) 
        { 
         if (result != ""){                      
          timer.Stop(); 
          Console.WriteLine(result); 
        } 
        } 
        else 
        { 
         timer.Stop(); 
         //cts.Cancel(); 
         //cts.Token.ThrowIfCancellationRequested(); 
        } 
       } 
      } 
      catch (OperationCanceledException) 
      { 
       Console.WriteLine(t.IsCanceled); // still its appear in false. 
      } 

Мое требование - задача не завершена ДО 10 секунд, нужно отменить задание.

Так что я устанавливаю таймер и смотрю до заданных секунд. его незавершенность означает отмену задачи и отображение сообщения об ошибке.

+3

Пожалуйста, укажите [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve). То, что вы показали, является неполным. – Igor

+1

Недостаточно отменить токен, вам нужно проверить код метода для отмены задания – VMAtm

+1

Можете ли вы показать код, в котором ожидает Task t? И чтобы быть верным, вы хотите отменить всю операцию, если для выполнения этого метода требуется более 20 секунд, не так ли? –

ответ

1

Из документации:

Целевые завершат в состоянии TaskStatus.Canceled при любом из следующих условий:

  1. Его CancellationToken был отмечен для отмены, прежде чем задача начала выполняться.

  2. Задача признала запрос аннулирования уже сообщенным CancellationToken, отправив исключение OperationCanceledException, которое имеет тот же CancellationToken.

  3. Задача признала запрос аннулирования уже сообщенным CancellationToken, вызвав метод ThrowIfCancellationRequested в CancellationToken.

Поэтому в основном вам нужно будет бросаться OperationCanceledException в вашей задачи, чтобы заставить государство, например, выполнив cts.Token.ThrowIfCancellationRequested() только после его отмены.

Но намерение этого механизма немного наоборот. Вы отменяете источник, когда пользователь нажимает кнопку отмены на вашей форме (вне вашей задачи), задача просто проверяет, была ли аннулирована просьба в некоторых случаях, чтобы отменить точки своего кода.

2

Вы должны передать токен вашему методу. Он должен проверить токен и соблюдать звонок по адресу Cancel() из CancellationTokenSource.

Или вы сами:

Task t = Task.Factory.StartNew(() => 
{ 
    myResult = method(); // Request processing in parallel 

    cts.Token.ThrowIfCancellationRequested(); // React on cancellation 
}, cts.Token); 

Полный пример таков:

async Task Main() 
{ 
    var cts = new CancellationTokenSource(); 
    var ct = cts.Token; 
    cts.CancelAfter(500); 

    Task t = null; 
    try 
    { 
     t = Task.Run(() => { Thread.Sleep(1000); ct.ThrowIfCancellationRequested(); }, ct); 
     await t; 
     Console.WriteLine(t.IsCanceled); 
    } 
    catch (OperationCanceledException) 
    { 
     Console.WriteLine(t.IsCanceled); 
    } 
} 

Выход что OperationCanceledException брошено и результат

Правда

если удалить ct.ThrowIfCancellationRequested(); части будет показывать

ложного

Edit:

Теперь вы обновили вопрос, некоторые комментарии по этому поводу. Во-первых, вам больше не понадобится таймер, так как вы используете метод CancelAfter. Во-вторых, вам нужно выполнить await. Так что делает что-то вроде этого:

string result = ""; 
cts.CancelAfter(10000); 
Task t = null; 
try 
{ 
    t = Task.Run(() => 
    { 
     using (var stream = new WebClient().OpenRead("http://www.rediffmail.com")) 
     { 
      cts.Token.ThrowIfCancellationRequested(); 
      result = "success!"; 
     } 
    }, cts.Token); 

    await t; 
} 
catch (OperationCanceledException) 
{ 
    Console.WriteLine(t.IsCanceled); 
} 

Это должно показать, что t.IsCanceled является true, но, конечно, только тогда, когда вызов WebClient занимает больше времени, что 10 секунд.

+0

Задача t = Задача.Factory.StartNew (() => { myResult = метод(); // Обработка запроса параллельно }, cts.Token); // Через некоторое время cts.cancel cts.Token.ThrowIfCancellationRequested(); Возможно ли это или нет? здесь t.iscancelled никогда не приходит с истиной. –

+0

Можете ли вы показать код, в котором ожидает Task t? И чтобы быть верным, вы хотите отменить всю операцию, если для выполнения этого метода требуется более 20 секунд, не так ли? –

+0

Как поделиться кодом? здесь появляются слишком длинные персонажи. –

 Смежные вопросы

  • Нет связанных вопросов^_^