Await in catch block

C#AsynchronousAsync AwaitC# 5.0C# 6.0

C# Problem Overview


I have the following 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" ) );
}

Basically I want to download from a URL and when it fails with an exception I want to download from another URL. Both time async of course. However the code does not compile, because of

> error CS1985: Cannot await in the body of a catch clause

OK, it's forbidden for whatever reason but what's the correct code pattern here?

EDIT:

The good news is that C# 6.0 will likely allow await calls both in catch and finally blocks.

C# Solutions


Solution 1 - C#

Update: C# 6.0 supports await in catch


Old Answer: You can rewrite that code to move the await from the catch block using a flag:

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

Solution 2 - C#

Awaiting in a catch block is now possible as of the End User Preview of Roslyn as shown here (Listed under Await in catch/finally) and will be included in C# 6.

The example listed is

trycatch { await … } finally { await … }

Update: Added newer link, and that it will be in C# 6

Solution 3 - C#

This seems to work.

        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;

Solution 4 - C#

Give this a try:

         try
        {
            await AsyncFunction(...);
        }

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

(See the Wait() ending)

Solution 5 - C#

Use C# 6.0. see this Link

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

Solution 6 - C#

You could put the await after the catch block followed by a label, and put a goto in the try block. (No, really! Goto's aren't that bad!)

Solution 7 - C#

The pattern I use to rethrow the exception after await on a fallback task:

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

if (capturedException != null)
{
  await FallbackWork();
  capturedException.Throw();
}

Solution 8 - C#

You can use a lambda expression as follows:

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

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

        lambda(ex);
    }



Solution 9 - C#

In a similar instance, I was unable to await in a catch block. However, I was able to set a flag, and use the flag in an if statement (Code below)

---------------------------------------...

boolean exceptionFlag = false; 

try 
{ 
do your thing 
} 
catch 
{ 
exceptionFlag = true; 
} 

if(exceptionFlag == true){ 
do what you wanted to do in the catch block 
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGy&#246;rgy Bal&#225;ssyView Question on Stackoverflow
Solution 1 - C#svickView Answer on Stackoverflow
Solution 2 - C#CraigView Answer on Stackoverflow
Solution 3 - C#DarraghView Answer on Stackoverflow
Solution 4 - C#RonView Answer on Stackoverflow
Solution 5 - C#user5447154View Answer on Stackoverflow
Solution 6 - C#Protector oneView Answer on Stackoverflow
Solution 7 - C#hansmaadView Answer on Stackoverflow
Solution 8 - C#IzmotoView Answer on Stackoverflow
Solution 9 - C#Amanda BereniceView Answer on Stackoverflow