2012-11-29 2 views
5

Ich habe verschiedene Aufgaben aus verschiedenen Dateien zu lesen und ein Wort in ihnen zu finden. Ich habe sie in eine Aufgabe gestellt hatten, die ich mit WaitAny Methode wie folgt beginnen:Wie alle Aufgaben zu stoppen, wenn man in c fertig ist #

foreach (string file in filesList) 
     { 
      files[i] = Task.Factory.StartNew(() => 
      { 
       mySearch.Invoke(file); 
      }); 
      i++; 
     } 
     System.Threading.Tasks.Task.WaitAny(files); 

Ich möchte alle anderen Aufgaben stoppen, sobald eine der Aufgaben beendet (es endet, wenn er das Wort gründet). Im Moment kann ich mit Waitanya wissen, wann eine Aufgabe beendet ist, aber ich weiß nicht, wie ich wissen könnte, welche beendet wurde und wie man andere Aufgaben stoppt. Was wäre der beste Weg, dies zu erreichen?

+0

Hinterlässt die abgeschlossene Aufgabe irgendwo ein Ergebnis? Das könnte die Identifizierung der Aufgabe beinhalten. Die erste auszuführende Aufgabe könnte auch ein Ereignis festlegen, das von jeder Aufgabe in seiner Hauptschleife überprüft wird und alle anderen Aufgaben zum Beenden veranlasst. – HABO

+0

in der mySearch.Invoke, sollten sie eine Schleife durchlaufen Wort für Wort. Sie können dann ein Flag hinzufügen, so dass die Schleife bricht, wenn das Flag signalisiert wird, wenn eine Aufgabe das Wort findet, können Sie das Flag signalisieren – ComfortablyNumb

Antwort

2

Sie können einzelne CancellationToken verwenden, die alle Aufgaben teilen. Inside mySearch.Invoke Methode überprüfen Wert von token.IsCancellationRequested, um Aufgabe abzubrechen. Wenn eine Aufgabe beendet ist, löschen Sie die anderen über CancellationTokenSource.Cancel().

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

foreach (string file in filesList) 
{ 
    // pass cancellation token to your task 
    files[i] = Task.Factory.StartNew(() => mySearch.Invoke(file, token), token); 
    i++; 
} 

Task.WaitAny(files); 
tokenSource.Cancel(); 

BTW können Sie Token zwingen OperationCanceledException zu werfen, wenn die Quelle durch den Aufruf token.ThrowIfCancellationRequested()

2

abgebrochen wird, wenn eine Aufgabe erstellen, können Sie einen Pass CancelationToken. Setzen Sie dieses Token, wenn eine der Aufgaben beendet ist. Dadurch werden verbleibende Aufgaben mit diesem Token zu not execute. Laufende Aufgaben können eine OperationCanceledException erhalten und auch stoppen.

1

Ich empfehle sehr zu lesen How do I cancel non-cancelable async operations? von Stephen Toub. Im Wesentlichen müssen Sie alle diese Aufgaben abbrechen, aber derzeit haben Sie keinen Mechanismus, um sie abzubrechen.

Der ideale Ansatz wäre, eine CancellationTokenSource vor dem foreach zu erstellen, übergeben Sie die CancellationToken von dieser Quelle an jede der untergeordneten Aufgaben, überprüfen Sie dieses Token in regelmäßigen Abständen und aufhören zu arbeiten, wenn Sie bemerken, dass es Kündigung anzeigt. Sie können dann die Token-Quelle in der WhenAny Fortsetzung abbrechen.

Wenn das keine Option ist, müssen Sie entscheiden, ob es wirklich wichtig ist, die Aufgaben zu stoppen (was wirklich nicht möglich ist) oder wenn Sie nur mit Ihrem Code fortfahren müssen, ohne zu warten (das ist einfach genug zu tun).

Verwandte Themen