Esperar en el bloque catch

Tengo el siguiente código:

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

Básicamente quiero descargar desde una URL y cuando falla con una excepción deseo descargar desde otra URL. Tanto el tiempo asincrónico por supuesto. Sin embargo, el código no se comstack, debido a

error CS1985: no puede esperar en el cuerpo de una cláusula de captura

OK, está prohibido por cualquier razón, pero ¿cuál es el patrón de código correcto aquí?

EDITAR:

La buena noticia es que es probable que C # 6.0 permita llamadas en espera tanto en los bloques catch como finally .

Actualización: los soportes de C # 6.0 esperan en la captura


Respuesta anterior : Puede volver a escribir ese código para mover la await del bloque catch usando una bandera:

 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" ) ); 

Esperar en un bloque catch ahora es posible a partir de la vista previa del usuario final de Roslyn, como se muestra aquí (enumerados en Aguardar en catch / finally) y se incluirá en C # 6.

El ejemplo mencionado es

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

Actualización: Se agregó un enlace más nuevo, y estará en C # 6

Esto parece funcionar

  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; 

Prueba esto:

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

(Ver el final de Wait() )

Use C # 6.0. ver este enlace

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

El patrón que uso para volver a lanzar la excepción después de esperar en una tarea alternativa:

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

Puede usar una expresión lambda de la siguiente manera:

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

Podrías poner la await después del bloque catch seguido de una label , y poner un goto en el bloque try. (¡No, de verdad! ¡Los de Goto no son tan malos!)

En una instancia similar, no pude esperar en un bloque catch. Sin embargo, pude establecer una bandera y usar la bandera en una statement if (Código a continuación)

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

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