2013-04-28 22 views
7

Ho difficoltà a comprendere loopState.Stop() e loopState.Break(). Ho letto MSDN e diversi post su di esso, ma sono ancora confuso.Stop vs Break in Parallel.Per

Quello che ho capito è che ogni partizionatore di iterazione fornisce gli indici rimanenti per i thread da elaborare e loopState.Stop() interrompe tutti i thread e loopState.Break() interrompe il thread corrente.

lascia tuttavia considerare seguente situazione:

Parallel.For(0, 100, (i, loopState) => 
{ 
    if (i >= 10) 
     loopState.Break(); 
    Debug.Write(i); 
}); 

per questo ciclo ho risultato vuoto sanitario:

0 25 1 2 3 4 5 6 7 8 9 10 

Non ho idea del perché nel risultato v'è 10 e 25 numeri.

Chiunque può aiutare?

P.S. Ho CPU i5 520M (2 core => 4 thread)

risposta

9

loopState.Break() non interrompe la funzione come un return. Pertanto, la riga successiva allo loopState.Break() verrà comunque eseguita. Dopo che l'ambito è terminato per quel numero, for controlla se è stato chiamato lo loopState.Break(). In tal caso, tutti i cicli sono autorizzati a continuare fino al raggiungimento del numero chiamato Break.

Nel tuo esempio, i cicli da 0 a 24 si interromperanno contemporaneamente al ciclo da 25 a 49 (e visualizzeranno i loro numeri di "interruzione").

Loop 50..74 e 75..99 non sarà ancora di iniziare perché il secondo anello 25..49 ha già interrotto il tutto per-operazione, poiché il loro numero staring sono superiori allora il numero di rottura 10.

+0

Quindi loopState.Break() chiude tutti i thread? Uso ciò che loopState.Stop() fa. –

+0

Per chiarire il mio commento precedente: ora capisco come si fermino i primi due cicli, ma perché gli altri due thread non iniziano nemmeno? Break è in grado di terminare più di un thread? Se sì, come funziona? –

+0

Vedi per una buona risposta su Stop vs Break: http://stackoverflow.com/questions/8818203/what-is-difference-between-loopstate-break-loopstate-stop-and-cancellationt –

3

da the documentation of Break():

interruzione può essere utilizzato per comunicare alla rete che nessun'altra iterazioni dopo l'iterazione corrente devono necessariamente essere eseguite. Ad esempio, se Break viene chiamato dalla 100a iterazione di un ciclo for che itera in parallelo da 0 a 1000, tutte le iterazioni inferiori a 100 dovrebbero essere ancora eseguite, ma le iterazioni da 101 a 1000 non sono necessarie.

Ciò significa che l'iterazione corrente verrà comunque completata (quindi 10 viene stampato). Break() inoltre non è in grado di viaggiare nel tempo, quindi lo 25 rimarrà stampato. Quello che Break() significa è che nessuna nuova iterazioni oltre 10 verranno avviate.

0

La pausa assicura che tutte le iterazioni attualmente in esecuzione siano terminate.

Stop termina tutto.

1

if (i >= 10) loopState.Break(); continuerà l'iterazione corrente. Quindi viene stampato 10.

Tuttavia, le iterazioni (i> = 10) dopo il loopState.Break() chiamato non verranno avviate.

Ma perché 25 viene stampato? L'immagine seguente spiegherà perché. Dato che hai 4 thread, 0-99 sarà diviso in 4.

1 ° thread ha: 0-24.
2 ° discussione c'è: 25 - 49.
terzo thread ha: 50 - 74.
4 thread ha: 75 - 99.

Sulla base della mia comprensione, ogni ciclo filo volontà i numeri stesso. In base a this post, è indicato

È possibile eseguire ulteriori iterazioni, se erano già state avviate quando è stato chiamato Break.

Poiché il 2 ° thread è iniziato quasi alla stessa ora del 1 ° thread, viene stampato 0, 25. Quindi viene chiamato if (i >= 10) loopState.Break(); durante il ciclo 25 nella seconda discussione.

Gli anelli in 3a e 4a filettatura non sono stati avviati prima che venga chiamato Break(), quindi non è stato stampato alcun numero maggiore di 10.

immagine ref: http://www.albahari.com/threading/part5.aspx

0

Tutti i metodi di statica Parallel classe restituisce ParallelLoopResult .Questa oggetto ha due proprietà - IsCompleted e LowestBreakIteration

Quando usiamo loopState.Break(), LowestBreakIteration restituisce un numero intero che rappresenta l'iterazione basso da cui è stata chiamata la dichiarazione Break

Quando si utilizza loopState.Stop(), LowestBreakIteration Restituisce null