Attraper une exception levée dans un rappel asynchrone

J’ai une méthode qui prend un argument de rappel pour une exécution asynchrone, mais le bloc catch ne semble pas intercepter les exceptions this.Submit par l’appel synchrone ( this.Submit fait référence à une méthode synchrone).

 public void Submit(FileInfo file, AnswerHandler callback) { SubmitFileDelegate submitDelegate = new SubmitFileDelegate(this.Submit); submitDelegate.BeginInvoke(file, (IAsyncResult ar) => { ssortingng result = submitDelegate.EndInvoke(ar); callback(result); }, null); } 

Y a-t-il un moyen d’attraper l’exception levée par le nouveau thread et de l’envoyer au thread d’origine? En outre, est-ce la manière “appropriée” de gérer les exceptions asynchrones? J’ai écrit mon code afin qu’il puisse s’appeler comme ceci (en supposant que le problème de l’exception soit résolu):

 try { target.Submit(file, (response) => { // do stuff }); } catch (Exception ex) { // catch stuff } 

mais y a-t-il une manière plus appropriée ou élégante de faire ceci?

Ce n’est pas une solution de «bonne pratique», mais je pense que c’est une solution simple qui devrait fonctionner.

Au lieu de définir le délégué comme

 private delegate ssortingng SubmitFileDelegate(FileInfo file); 

le définir comme

 private delegate SubmitFileResult SubmitFileDelegate(FileInfo file); 

et définissez le SubmitFileResult comme suit:

 public class SubmitFileResult { public ssortingng Result; public Exception Exception; } 

Ensuite, la méthode qui effectue réellement la soumission du fichier (non indiquée dans la question) devrait être définie comme suit:

 private static SubmitFileResult Submit(FileInfo file) { try { var submissionResult = ComplexSubmitFileMethod(); return new SubmitFileResult { Result = submissionResult }; } catch (Exception ex) { return new SubmitFileResult {Exception = ex, Result = "ERROR"}; } } 

De cette façon, vous examinerez l’object de résultat, vérifiez s’il contient le champ Résultat ou Exception et agissez en conséquence.

Si vous ciblez .NET 4.0, vous pouvez utiliser la nouvelle bibliothèque de tâches parallèles et observer la propriété Exception l’object Task .

 public Task Submit(FileInfo file) { return Task.Factory.StartNew(() => DoSomething(file)); } private void DoSomething(FileInfo file) { throw new Exception(); } 

Ensuite, utilisez-le comme ceci:

 Submit(myFileInfo).ContinueWith(task => { // Check task.Exception for any exceptions. // Do stuff with task.Result }); 

DoSomething est la méthode que vous souhaitez appeler de manière asynchrone et le délégué que vous passez à ContinueWith est votre rappel.

Vous trouverez plus d’informations sur la gestion des exceptions dans TPL à l’ adresse suivante : http://msdn.microsoft.com/en-us/library/dd997415.aspx

Bref non.

Lorsque vous appelez submitDelegate.BeginInvoke , le nouveau thread est submitDelegate.BeginInvoke , il retourne et quitte rapidement votre bloc try / catch (pendant que le nouveau thread s’exécute en arrière-plan).

Vous pouvez cependant intercepter toutes les exceptions non gérées de la manière suivante:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(YourException);

Cependant, cela interceptera tout dans le domaine d’application (pas seulement votre méthode asynchrone).