Ожидание в блоке catch

У меня есть следующий код:

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

В принципе, я хочу загрузить с URL-адреса, и когда он завершится с исключением, я хочу загрузить с другого URL-адреса. И время как раз асинхронно, конечно. Однако код не компилируется из-за

ошибка CS1985: не может ждать в теле catch

ОК, это запрещено по какой-то причине, но каков правильный код здесь?

РЕДАКТИРОВАТЬ:

Хорошей новостью является то, что C # 6.0, вероятно, позволит ждать вызовов как в catch, так и в конце блоков .

Обновление: поддержка C # 6.0 в catch


Старый ответ : вы можете переписать этот код, чтобы переместить await из блока catch с помощью флага:

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

Ожидание в блоке catch теперь возможно с предварительного просмотра пользователя Roslyn, как показано здесь (перечислено под заголовком Await в catch / finally) и будет включено в C # 6.

В приведенном примере

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

Обновление: добавлена ​​новая ссылка и что она будет в C # 6

Кажется, это работает.

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

Попробуйте:

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

(См. Окончание Wait() )

Используйте C # 6.0. см. ссылку

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

Образец, который я использую для повторного исключения исключения после ожидания в резервной задаче:

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

Вы можете использовать выражение lambda следующим образом:

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

Вы можете поставить await после блока catch, за которым следует label , и поместить goto в блок try. (Нет, действительно, Гото не так уж плохо!)

В аналогичном случае я не смог дождаться в блоке catch. Тем не менее, я смог установить флаг и использовать флаг в инструкции if (код ниже)

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

 boolean exceptionFlag = false; try { do your thing } catch { exceptionFlag = true; } if(exceptionFlag == true){ do what you wanted to do in the catch block } 
  • Как включить функцию C # 6.0 в Visual Studio 2013?
  • Строительство TFS 2013 .NET 4.6 / C # 6.0
  • В чем смысл запланированного модификатора доступа к закрытой защите?
  • В чем разница между свойствами автогенератора и свойствами тела выражения?
  • Строки интерполяции длинной строки в C # 6
  • Давайте будем гением компьютера.