c# - generate - Esperar en el bloque catch
params comments c# (9)
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 compila, 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 .
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();
}
En una instancia similar, no pude esperar en un bloque catch. Sin embargo, pude establecer una bandera y usar la bandera en una declaració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
}
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<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;
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!)
Prueba esto:
try
{
await AsyncFunction(...);
}
catch(Exception ex)
{
Utilities.LogExceptionToFile(ex).Wait();
//instead of "await Utilities.LogExceptionToFile(ex);"
}
(Ver el final de Wait()
)
Puede usar una expresión lambda de la siguiente manera:
try
{
//.....
}
catch (Exception ex)
{
Action<Exception> lambda;
lambda = async (x) =>
{
// await (...);
};
lambda(ex);
}
Use C # 6.0. ver este enlace
public async Task SubmitDataToServer()
{
try
{
// Submit Data
}
catch
{
await LogExceptionAsync();
}
finally
{
await CloseConnectionAsync();
}
}
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" ) );