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
Await in catch block
提问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.
回答by svick
Update:C# 6.0 supports await in catch
Old Answer: You can rewrite that code to move the awaitfrom the catchblock using a flag:
旧答案:您可以重写该代码以使用标志await从catch块中移动:
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
回答by Izmoto
You can use a lambda expression as follows:
您可以按如下方式使用 lambda 表达式:
try
{
//.....
}
catch (Exception ex)
{
Action<Exception> lambda;
lambda = async (x) =>
{
// await (...);
};
lambda(ex);
}

