Attendez dans le bloc de capture

J’ai le code suivant:

WebClient wc = new WebClient(); ssortingng result; try { result = await wc.DownloadSsortingngTaskAsync( new Uri( "http://badurl" ) ); } catch { result = await wc.DownloadSsortingngTaskAsync( new Uri( "http://fallbackurl" ) ); } 

Fondamentalement, je veux télécharger depuis une URL et quand elle échoue avec une exception que je veux télécharger depuis une autre URL. Les deux temps async bien sûr. Cependant, le code ne comstack pas, à cause de

Erreur CS1985: Impossible d’attendre dans le corps d’une clause catch

OK, c’est interdit pour quelque raison que ce soit, mais quel est le modèle de code correct ici?

MODIFIER:

La bonne nouvelle est que C # 6.0 autorisera probablement les appels en attente à la fois dans les blocs catch et finally .

Mise à jour: les supports C # 6.0 attendent dans l’attente


Ancienne réponse : Vous pouvez réécrire ce code pour déplacer l’ await du bloc catch aide d’un indicateur:

 WebClient wc = new WebClient(); ssortingng result = null; bool downloadSucceeded; try { result = await wc.DownloadSsortingngTaskAsync( new Uri( "http://badurl" ) ); downloadSucceeded = true; } catch { downloadSucceeded = false; } if (!downloadSucceeded) result = await wc.DownloadSsortingngTaskAsync( new Uri( "http://fallbackurl" ) ); 

L’attente dans un bloc catch est désormais possible à partir de l’aperçu utilisateur final de Roslyn, comme illustré ici (répertorié sous Attente dans catch / finally) et sera inclus dans C # 6.

L’exemple répertorié est

 try … catch { await … } finally { await … } 

Mise à jour: Ajout d’un nouveau lien, et qu’il sera en C # 6

Cela semble fonctionner.

  WebClient wc = new WebClient(); ssortingng result; Task downloadTask = wc.DownloadSsortingngTaskAsync(new Uri("http://badurl")); downloadTask = downloadTask.ContinueWith( t => { return wc.DownloadSsortingngTaskAsync(new Uri("http://google.com/")).Result; }, TaskContinuationOptions.OnlyOnFaulted); result = await downloadTask; 

Essayez ceci:

  try { await AsyncFunction(...); } catch(Exception ex) { Utilities.LogExceptionToFile(ex).Wait(); //instead of "await Utilities.LogExceptionToFile(ex);" } 

(Voir la fin de Wait() )

Utilisez C # 6.0. voir ce lien

 public async Task SubmitDataToServer() { try { // Submit Data } catch { await LogExceptionAsync(); } finally { await CloseConnectionAsync(); } } 

Le modèle que j’utilise pour relancer l’exception après l’attente d’une tâche de secours:

 ExceptionDispatchInfo capturedException = null; try { await SomeWork(); } catch (Exception e) { capturedException = ExceptionDispatchInfo.Capture(e); } if (capturedException != null) { await FallbackWork(); capturedException.Throw(); } 

Vous pouvez utiliser une expression lambda comme suit:

  try { //..... } catch (Exception ex) { Action lambda; lambda = async (x) => { // await (...); }; lambda(ex); } 

Vous pouvez mettre l’ await après le bloc catch suivi d’une label et mettre un goto dans le bloc try. (Non, vraiment! Goto n’est pas si mal!)

Dans un cas similaire, je n’ai pas pu attendre dans un bloc catch. Cependant, j’ai pu définir un drapeau et utiliser le drapeau dans une instruction if (Code ci-dessous)

—————————————…

 boolean exceptionFlag = false; try { do your thing } catch { exceptionFlag = true; } if(exceptionFlag == true){ do what you wanted to do in the catch block }