wake-up-neo.com

Warten Sie im Fangblock

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 .

82

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

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

24
Craig

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;
9
Darragh

Probieren Sie es aus:

         try
        {
            await AsyncFunction(...);
        }

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

(Siehe die Wait() -Ende)

5
Ron

Verwenden Sie C # 6.0. siehe dies Link

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

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();
}
1
hansmaad

Sie können einen Lambda-Ausdruck wie folgt verwenden:

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

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

        lambda(ex);
    }
1
Izmoto

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 
}
0
Amanda Berenice

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!)

0
Protector one