2013-04-16 9 views
5

Qual è la differenza tra le operazioni di annullamento rispetto all'operazione loopState (interruzione/arresto)?parallel.foreach - loopState.Stop() rispetto a Cancellazione

private static CancellationTokenSource cts; 
public static loopingMethod() 
{ 
cts = new CancellationTokenSource(); 
try 
{ 
    ParallelOptions pOptions = new ParallelOptions(); 
    pOptions.MaxDegreeOfParallelism = 4; 
    pOptions.CancellationToken = cts.Token; 
    Parallel.ForEach(dictObj, pOptions, (KVP, loopState) => 
    { 
     pOptions.CancellationToken.ThrowIfCancellationRequested(); 
     parallelDoWork(KVP.Key, KVP.Value, loopState); 
    }); //End of Parallel.ForEach loop 
} 
catch (OperationCanceledException e) 
{ 
//Catestrophic Failure 
return -99; 
} 
} 

public static void parallelDoWork(string Id, string Value, ParallelLoopState loopState) 
{ 
    try{ 
     throw new exception("kill loop"); 
    } 
    catch(exception ex) 
    { 
     if(ex.message == "kill loop") 
     { 
      cts.Cancel(); 
      //Or do I use loopState here? 
     } 
    } 
} 

Perché dovrei voler usare l'operazione di cancellazione ParallelOptions rispetto al loopState.Break(); o loopState.Stop(); o viceversa?

risposta

2

Vai a questa article

"Impostazione di un gettone cancellazione consente di abbandonare Invoke (ricordiamo che quando un delegato genera un'eccezione, l'eccezione viene ingerito e solo ri-lanciato dal Invoke dopo tutte le altre i delegati sono stati eseguito). "

Scenario 1. Immagina di avere un utente che sta per inviare messaggi a tutti gli amici ex- [ragazza | ragazzo]. Fanno clic su Invia e poi tornano in sé e vogliono annullarlo. Usando il token di cancellazione sono in grado di impedire che altri messaggi escano. Quindi, se hai un processo a lungo termine che può essere cancellato, usa il token di cancellazione.

Scenario 2 D'altra parte, se non si desidera interrompere un processo, utilizzare le normali eccezioni dello stato del ciclo in modo che le eccezioni vengano ingerite fino al termine di tutti i thread.

Scenario 3 Se si dispone di un processo intensivo di I/O, probabilmente si desidera utilizzare async/await e non parallel.foreach. Dai un'occhiata a Microsoft task-based asynchronous pattern.

+0

Non sono sicuro che risponda alla domanda originale di quando avrei usato loopState sull'annullamento ... Puoi analizzare questa risposta e spiegarla di più? – webdad3

+0

Apprezzo i diversi scenari. Questo ha molto più senso per me. – webdad3

2

ParallelLoopState.Break/Stop hanno una semantica ben definita specifica per l'esecuzione del ciclo. Cioè usando questi puoi essere molto specifico su come vuoi che il ciclo si interrompa. Un CancellationToken d'altra parte è il meccanismo di arresto generico in TPL, quindi non fa nulla di speciale per i loop paralleli. Il vantaggio dell'utilizzo del token è che può essere condiviso tra altre funzionalità di TPL, in modo da poter avere un'attività e un ciclo controllati dallo stesso token.

+0

In realtà, CancellationToken ha un effetto speciale sui loop paralleli. Se ParallelOptions.CancellationToken viene cancellato, ParallelLoopState.ShouldExitCurrentIteration diventa falso. Quindi un'attività a lunga esecuzione (che potrebbe non essere stata annullata dal ciclo) può controllare questa proprietà e interromperne il funzionamento. https://msdn.microsoft.com/en-us/library/system.threading.tasks.parallelloopstate.shouldexitcurrentiteration(v=vs.110).aspx –

Problemi correlati