Ich habe folgenden Code:
WebClient wc = new WebClient();
string result;
try
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://badurl" ) );
}
catch
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://fallbackurl" ) );
}
Grundsätzlich möchte ich von einer URL herunterladen, und wenn dies mit einer Ausnahme fehlschlägt, möchte ich von einer anderen URL herunterladen. Beide Male natürlich asynchron. Der Code wird jedoch aufgrund von nicht kompiliert
fehler CS1985: Im Text einer catch-Klausel kann nicht gewartet werden
OK, es ist aus irgendeinem Grund verboten, aber wie lautet hier das richtige Codemuster?
EDIT:
Die gute Nachricht ist, dass C # 6.0 das Warten auf Aufrufe in catch und finally-Blöcken wahrscheinlich zulässt .
Update: C # 6.0-Unterstützung wartet auf catch
Alte Antwort : Sie können diesen Code umschreiben, um await
mit einem Flag aus dem catch
-Block zu verschieben:
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" ) );
Das Warten in einem Catch-Block ist jetzt in der Endbenutzer-Vorschau von Roslyn möglich wie hier gezeigt (unter Warten in Catch/Endlich und wird in C # 6 aufgenommen.
Das aufgeführte Beispiel ist
try … catch { await … } finally { await … }
Update: Neuerer Link hinzugefügt, und das wird in C # 6 sein
Das scheint zu funktionieren.
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;
Probieren Sie es aus:
try
{
await AsyncFunction(...);
}
catch(Exception ex)
{
Utilities.LogExceptionToFile(ex).Wait();
//instead of "await Utilities.LogExceptionToFile(ex);"
}
(Siehe die Wait()
-Ende)
Verwenden Sie C # 6.0. siehe dies Link
public async Task SubmitDataToServer()
{
try
{
// Submit Data
}
catch
{
await LogExceptionAsync();
}
finally
{
await CloseConnectionAsync();
}
}
Das Muster, mit dem ich die Ausnahme nach dem Warten auf eine Fallback-Task erneut auslöse:
ExceptionDispatchInfo capturedException = null;
try
{
await SomeWork();
}
catch (Exception e)
{
capturedException = ExceptionDispatchInfo.Capture(e);
}
if (capturedException != null)
{
await FallbackWork();
capturedException.Throw();
}
Sie können einen Lambda-Ausdruck wie folgt verwenden:
try
{
//.....
}
catch (Exception ex)
{
Action<Exception> lambda;
lambda = async (x) =>
{
// await (...);
};
lambda(ex);
}
In einem ähnlichen Fall konnte ich nicht in einem Fangblock warten. Ich konnte jedoch ein Flag setzen und das Flag in einer if-Anweisung verwenden (Code unten)
---------------------------------------...
boolean exceptionFlag = false;
try
{
do your thing
}
catch
{
exceptionFlag = true;
}
if(exceptionFlag == true){
do what you wanted to do in the catch block
}
Sie können das await
nach dem catch-Block, gefolgt von einem label
, und ein goto
in den try-Block einfügen. (Nein, wirklich! Goto ist nicht so schlimm!)