2016-04-10 6 views
0

In einem bestimmten Geschäftsszenario werden mehrere Aufgaben parallel ausgeführt. Ich benutze CancellationToken, um diese Aufgaben abzubrechen, wann immer der Endbenutzer es wünscht. Ich muss auch alle Aufgaben neu starten, nachdem sie für einen bestimmten Zeitraum ausgeführt wurden, sagen wir 3 Stunden. Dafür verwende ich:So erfahren Sie, ob eine Aufgabe abgebrochen wurde oder die Wartezeit abgelaufen ist

_cts.CancelAfter(TimeSpan.FromHours(3)) 

Das funktioniert gut. Wenn jedoch 3 Stunden vergangen sind, werden die Aufgaben automatisch abgebrochen und kommen wieder heraus. Daher bin ich nicht in der Lage, die beiden Szenarien getrennt zu erkennen, nämlich: War die Stornierung fällig, weil der Benutzer stornieren wollte oder weil 3 Stunden abgelaufen waren.

Ich bin bewusst, dass wir eine Datetime Variable mit der letzten Laufzeit und schieben Sie diese in unserer Aufgabe verwenden können. Wir können dann die Aufgabe auf der Grundlage der aktuellen Zeitdifferenz und des letzten Durchlaufs beenden. Aber ich habe mehr darüber nachgedacht, wie TPL dabei helfen kann.

Antwort

1

Ich denke, es gibt keinen Weg mit nur TPL. Ich habe eine Abhilfe mit System.Timers.Timer, hier ist mein Beispiel:

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(); 
    } 

Sie deklarieren einen Timer, der in 10 Sekunden verstreichen. Nach dieser Zeit Elapsed Ereignis wird die Lambda-Funktion auslösen und Sie können Ihre Logik dort setzen. Die andere Möglichkeit, die Aufgabe abzubrechen, ist, wenn der Benutzer 'q' antippt, und Sie können eine andere Logik dort setzen.

Hoffe, das wird dir helfen

+0

Thx. Das hilft. – Kallol

0

Sicherlich, wenn Sie in Reaktion auf Benutzereingaben abbrechen können Sie einen Flag in den UI-Event-Handler gesetzt?

Dies wird nicht durch ein Timeout eingestellt werden und somit könnte man sie unterscheiden.

Wenn die UI Löschung einzelner Arbeitsplätze ermöglicht dann könnten Sie eine Flagge als Eigenschaft auf jedem Job Kontext aus.

Verwandte Themen