Non gérée OperationCanceledException lors de la levée de Parallèle.ForEach
Je suis en train d'autoriser l'annulation d'une Parallel.ForEach
boucle. Selon cet article MSDN, il est possible, et je suis à la suite de leur codage.
//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);
}
Cependant, quand je l'appelle cts.Cancel();
de l'utilisateur-fonction accessible, l'application se bloque sur la ligne marquée par des astérisques ci-dessus avec l'erreur:
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:
J'ai le gestionnaire d'Exception là, donc je ne comprends pas le crash. Des idées?
- Je ne vois pas le problème que vous décrivez, la
catch
fonctionne très bien pour moi. Pourriez-vous poster une complète mais à court de code qui montre votre problème? - Je ne pense pas que l'application est tombé en panne, du moins pas avec cette exception. Votre application n'a pas planté (comment savez-vous qu'il est tombé en panne?), ou ce n'est pas la dernière exception qui se produit.
- Oui, vous aviez raison. Je courais dans le débogueur et quand j'ai vu l'exception de stopper l'exécution, j'ai pensé que c'était une exception qui serait le plantage de l'application. Je ne connaissais pas certaines exceptions ne sont pas s'écraser ceux.
Vous devez vous connecter pour publier un commentaire.
Le problème est que
po.CancellationToken.ThrowIfCancellationRequested();
est explicitement lancer une exception, ce qui n'est pas gérée. Le gestionnaire d'exception peut être autour de laParrallel.ForEach()
appel, mais l'exception n'est pas gérée au sein de l'expression lambda. Supprimer la ligne ou ajouter un gestionnaire d'exception au sein de l'expression lambda et cela devrait fonctionner.Voir Annulation d'une Tâche est de lancer une exception pour plus d'informations.
ThrowIfCancellationRequested()
. Lancer une exception est que cette méthode fonctionne.ThrowIfCancellationRequested()
.