2012-11-29 4 views
5

Ho diversi compiti da leggere da diversi file e trovare una parola in loro. Li ho messi in un array compito che comincio con metodo WaitAny come segue:Come interrompere tutte le attività quando si è finito in C#

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

Vorrei smettere di tutte le altre attività, non appena uno dei compiti finiture (termina quando fonda la parola). Per il momento, con waitany, posso sapere quando finisce uno dei compiti, ma non so come potrei sapere quale è finito e come fermare altri compiti. Quale sarebbe il modo migliore per raggiungere questo obiettivo?

+0

L'attività completata lascia un risultato da qualche parte? Ciò potrebbe includere l'identificazione del compito. La prima attività da completare potrebbe anche impostare un evento, controllato da ogni attività nel suo ciclo principale, che causerebbe l'uscita di tutte le altre attività. – HABO

+0

in mySearch.Invoke, il loro dovrebbe essere un ciclo iterare di parola in parola. È quindi possibile aggiungere un flag in modo che il loop si interrompa quando viene segnalata la bandiera, quando qualsiasi attività trova la parola, è possibile segnalare la bandiera – ComfortablyNumb

risposta

2

È possibile utilizzare il singolo CancellationToken che tutte le attività condivideranno. All'interno del metodo mySearch.Invoke verificare il valore di token.IsCancellationRequested per annullare l'attività. Quando alcuni compiti saranno terminati, cancella gli altri tramite 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 è possibile forzare token per gettare OperationCanceledException quando la sorgente viene annullata chiamando token.ThrowIfCancellationRequested()

2

Quando si crea un'attività è possibile passare un CancelationToken. Imposta questo token quando termina una delle attività. Ciò causerà le attività rimanenti con questo token a not execute. Le attività in esecuzione possono ricevere un OperationCanceledException e fermarsi anche.

1

Consiglio vivamente di leggere How do I cancel non-cancelable async operations? di Stephen Toub. Essenzialmente ciò che devi fare è cancellare tutte queste attività, ma al momento non hai alcun meccanismo per cancellarle.

L'approccio ideale sarebbe quello di creare un CancellationTokenSource prima del foreach, passare il CancellationToken da quella fonte a ciascuna delle attività figlio, controllare periodicamente quel token e interrompere il lavoro quando si nota che è indicato come cancellazione. È quindi possibile annullare la sorgente di token nella continuazione WhenAny.

Se questa non è un'opzione, è necessario decidere se è importante interrompere effettivamente le attività (cosa che, in realtà, non è possibile fare) o se è sufficiente continuare con il codice senza attendere che finiscano (è abbastanza facile da fare).

Problemi correlati