2012-09-24 20 views
7

Sto tentando di consentire l'annullamento di un ciclo Parallel.ForEach. Secondo this MSDN article, è possibile, e sto seguendo la loro codifica.Operazione non gestitaCanceledException quando generata da Parallel.ForEach

// Tokens for cancellation 
ParallelOptions po = new ParallelOptions(); 
po.CancellationToken = cts.Token; 

try 
{ 
    Parallel.ForEach(queries, po, (currentQuery) => 
    { 
     // Execute query 
     ExecuteQuery(currentQuery); 

     // Throw exception if cancelled 
     po.CancellationToken.ThrowIfCancellationRequested(); // *** 
    }); 
} 
catch (OperationCanceledException cancelException) 
{ 
    Console.WriteLine(cancelException.Message); 
} 

Tuttavia, quando chiamo cts.Cancel(); da una funzione accessibile all'utente, l'applicazione si blocca sulla linea contrassegnati con l'asterisco sono obbligatori di cui sopra con l'errore:

System.OperationCanceledException was unhandled by user code 
    Message=The operation was canceled. 
    Source=mscorlib 
    StackTrace: 
    at System.Threading.CancellationToken.ThrowIfCancellationRequested() 
    at CraigslistReader.SearchObject.<>c__DisplayClass7.<bw_DoWork>b__5(Query currentQuery) in {PATH}:line 286 
    at System.Threading.Tasks.Parallel.<>c__DisplayClass2d`2.<ForEachWorker>b__23(Int32 i) 
    at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c() 
InnerException: 

ho il gestore di eccezioni proprio lì, in modo da Non capisco lo schianto. Qualche idea?

+0

Non vedo il problema che stai descrivendo, il 'catch' funziona bene per me. Potresti pubblicare un codice completo ma breve che mostri il tuo problema? – svick

+0

Non penso che l'app si sia arrestata in modo anomalo, almeno non con questa eccezione. O la tua app non si è arrestata in modo anomalo (come sai che si è arrestato in modo anomalo?) O questa non è l'ultima eccezione che si sta verificando. – usr

+0

@usr Sì, avevi ragione. Lo stavo eseguendo nel debugger e quando ho visto l'eccezione fermare il runtime, ho pensato che fosse un'eccezione che avrebbe fatto crashare l'app. Non sapevo che alcune eccezioni non si arrovellassero. – Doug

risposta

2

Il problema è che po.CancellationToken.ThrowIfCancellationRequested(); lancia esplicitamente un'eccezione, che non è gestita. Il gestore di eccezioni può essere intorno alla chiamata Parrallel.ForEach() ma l'eccezione non viene gestita all'interno dell'espressione lambda. Rimuovere la riga o aggiungere un gestore di eccezioni all'interno dell'espressione lambda e dovrebbe funzionare.

Vedere Cancelling a Task is throwing an exception per ulteriori informazioni.

+0

Quindi, stai dicendo che l'esempio MSDN è sbagliato? – svick

+0

@svick Possibilmente. Dai un'occhiata alla risposta che ho collegato e prova cosa suggerisce. Se funziona, funziona. – akton

+0

@akton: Ho provato a inserire try/catch all'interno dell'espressione di lamba e il risultato è ancora un errore di runtime. – Doug

Problemi correlati