Await in catch block

十年热恋 提交于 2019-11-26 08:24:30

问题


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.


回答1:


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



回答2:


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

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

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




回答3:


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;



回答4:


Give this a try:

         try
        {
            await AsyncFunction(...);
        }

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

(See the Wait() ending)




回答5:


Use C# 6.0. see this Link

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



回答6:


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



回答7:


You can use a lambda expression as follows:

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

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

        lambda(ex);
    }



回答8:


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




回答9:


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 
}


来源:https://stackoverflow.com/questions/8868123/await-in-catch-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!