2012-01-15 15 views
73

Tengo el siguiente código:esperan en bloque 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")); 
} 

Básicamente Quiero descargar desde una URL y cuando se produce un error con una excepción Quiero descargar desde otra URL. Tanto el tiempo asincrónico por supuesto. Sin embargo, el código no se compila, a causa de

CS1985 de error: No se puede esperar en el cuerpo de una cláusula catch

OK, que está prohibido por cualquier razón, pero ¿cuál es el patrón de código correcto en este caso?

EDIT:

La buena noticia es que C# 6.0 will likely allow await calls both in catch and finally blocks.

Respuesta

87

Actualización:C# 6.0 supports await in catch


respuesta Antiguo: Puede volver a escribir el código para mover el 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")); 
+7

Gracias svick, eso es bastante obvio, algo mejor, más conectado con asíncrono? –

+0

No creo que exista algo así. – svick

+3

En su caso, también puede usar la continuación de tareas. Pero el código en la respuesta de 'svick' es más limpio que el código que usa continuaciones. –

9

Esto parece funcionar.

 WebClient wc = new WebClient(); 
     string result; 
     Task<string> 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; 
24

espera en un bloque catch es ahora posible a partir del Usuario Final de vista previa de Roslyn as shown here (Listed under Await in catch/finally) y se incluirán en C# 6.

El ejemplo que aparece es

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

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

0

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

0

En una instancia similar, no pude esperar en un bloque catch. Sin embargo, pude establecer un indicador y usar el indicador en una instrucción 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 
} 
4

seguirlo:

  try 
     { 
      await AsyncFunction(...); 
     } 

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

(Véase el Wait() final)

1

el patrón me utilizar 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(); 
} 
2

Use C# 6.0.ver este Link

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

Usted puede usar una expresión lambda de la siguiente manera:

try 
    { 
     //..... 
    } 
    catch (Exception ex) 
    { 
     Action<Exception> lambda; 

     lambda = async (x) => 
     { 
      // await (...); 
     }; 

     lambda(ex); 
    } 
+0

Esto hace que el lambda 'async void', que no debe usarse, a menos que sea necesario. – svick

Cuestiones relacionadas