2016-04-10 2 views
0

В конкретном бизнес-сценарии параллельно выполняется несколько задач. Я использую CancellationToken для отмены этих задач всякий раз, когда пожелает конечный пользователь. Мне также нужно перезапустить все задачи после их запуска в течение определенного периода времени, скажем, 3 часа. Для этого я использую:Как узнать, была ли задача отменена или период ожидания превышает

_cts.CancelAfter(TimeSpan.FromHours(3)) 

Это прекрасно работает. Однако, когда 3 часа, задачи автоматически отменяются и выходят. Следовательно, я не могу определить два сценария отдельно, а именно: было ли аннулирование из-за того, что пользователь отказался или потому, что было 3 часа.

Я знаю, что мы можем использовать переменную Datetime, содержащую последнее время выполнения, и нажимать это внутри нашей задачи. Затем мы можем завершить задачу на основе текущей разницы во времени и в последний раз. Но я больше смотрел, как TPL может помочь решить эту проблему.

ответ

1

Я думаю, что нет возможности использовать только TPL. Я сделал обходной путь, используя System.Timers.Timer, вот мой пример:

public static void DifferencingCancelAfterAndCancel() 
    { 
     CancellationTokenSource tokenSource = new CancellationTokenSource(); 
     CancellationToken token = tokenSource.Token; 

     Task task = new Task(() => 
     { 
      for (int i = 0; i < int.MaxValue; i++) 
      { 
       token.ThrowIfCancellationRequested(); 
       token.WaitHandle.WaitOne(1000); 
       Console.WriteLine("To cancel task press 'q': " + i); 
      } 
     }, token); 

     task.Start(); 

     System.Timers.Timer timer = new System.Timers.Timer(10000); 
     timer.Elapsed += (sender, args) => 
     { 
      if (!task.IsCanceled) 
      { 
       tokenSource.Cancel(); 
       Console.WriteLine("Task was cancelled by timer!"); 
      } 
      else Console.WriteLine("Task has already been cancelled by user"); 
     }; 

     timer.Enabled = true; 

     var k = Console.ReadLine(); 
     if (k == "q") 
     { 
      if (!task.IsCanceled) 
      { 
       tokenSource.Cancel(); 
       Console.WriteLine("Task was cancelled by user!"); 
      } 
      else Console.WriteLine("Task has already been cancelled by timer"); 
     } 
     Console.WriteLine("Press any key to finish"); 
     Console.ReadLine(); 
    } 

Вы объявляете таймер, который будет истечь через 10 секунд. После этого времени Истекшее событие вызовет функцию лямбда, и вы можете поместить туда свою логику. Другой способ отменить задачу - это когда пользователь удаляет 'q', и вы можете добавить туда какую-то другую логику.

Надеюсь, это вам поможет

+0

Thx. Это помогает. – Kallol

0

Действительно, когда вы отменяете ответ на ввод пользователя, вы можете установить флаг в обработчике событий UI?

Это не будет установлено таймаутом, и вы можете их отличить.

Если пользовательский интерфейс позволяет отменить отдельные задания, вы можете выставить флаг как свойство в каждом контексте работы.

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