C# 在 catch 块中等待

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8868123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 04:52:43  来源:igfitidea点击:

Await in catch block

c#asynchronousasync-awaitc#-5.0c#-6.0

提问by Gy?rgy Balássy

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

基本上我想从一个 URL 下载,当它因异常而失败时,我想从另一个 URL 下载。当然,这两个时间都是异步的。但是代码不能编译,因为

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

错误 CS1985:无法在 catch 子句的主体中等待

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# 6.0 可能会允许在 catch 和 finally 块中调用 await

回答by svick

Update:C# 6.0 supports await in catch

更新:C# 6.0 支持在 catch 中等待



Old Answer: You can rewrite that code to move the awaitfrom the catchblock using a flag:

旧答案:您可以重写该代码以使用标志awaitcatch块中移动:

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

回答by Darragh

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;

回答by Craig

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.

从 Roslyn 的最终用户预览版开始,现在可以在 catch 块中等待,如下所示(在 catch/finally 中的等待下列出),并将包含在 C# 6 中。

The example listed is

列出的例子是

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

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

更新:添加了更新的链接,它将在 C# 6 中

回答by Protector one

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

您可以await在 catch 块之后加上 a label,然后将 agoto放在 try 块中。(不,真的!后藤并没有那么糟糕!)

回答by Amanda Berenice

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)

在类似的情况下,我无法在 catch 块中等待。但是,我能够设置一个标志,并在 if 语句中使用该标志(下面的代码)

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

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

boolean exceptionFlag = false; 

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

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

回答by Ron

Give this a try:

试试这个:

         try
        {
            await AsyncFunction(...);
        }

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

(See the Wait()ending)

(见Wait()结尾)

回答by hansmaad

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

回答by hansmaad

Use C# 6.0. see this Link

使用 C# 6.0。看到这个链接

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

回答by Izmoto

You can use a lambda expression as follows:

您可以按如下方式使用 lambda 表达式:

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

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

        lambda(ex);
    }