我有以下代码:
WebClient wc = new WebClient();
string result;
try
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://badurl" ) );
}
catch
{
result = await wc.DownloadStringTaskAsync( new Uri( "http://fallbackurl" ) );
}
基本上我想从URL下载,当它失败并出现异常时我想从另一个URL下载。两个时间都是异步的。但是由于
,代码无法编译错误CS1985:无法等待catch子句的正文
好的,不管出于什么原因这是禁止的,但这里的代码模式是什么?
修改
好消息是C# 6.0 will likely allow await calls both in catch and finally blocks。
答案 0 :(得分:97)
更新: C# 6.0 supports await in catch
旧答案:您可以重写该代码,使用标记从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" ) );
答案 1 :(得分:24)
现在可以在Roslyn as shown here (Listed under Await in catch/finally)的最终用户预览版中等待一个catch块,并将包含在C#6中。
列出的例子是
try … catch { await … } finally { await … }
更新:添加了更新的链接,并且它将在C#6中
答案 2 :(得分:9)
这似乎有效。
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;
答案 3 :(得分:5)
尝试一下:
try
{
await AsyncFunction(...);
}
catch(Exception ex)
{
Utilities.LogExceptionToFile(ex).Wait();
//instead of "await Utilities.LogExceptionToFile(ex);"
}
(参见Wait()
结尾)
答案 4 :(得分:2)
使用C#6.0。请参阅此Link
public async Task SubmitDataToServer()
{
try
{
// Submit Data
}
catch
{
await LogExceptionAsync();
}
finally
{
await CloseConnectionAsync();
}
}
答案 5 :(得分:1)
用于在等待回退任务后重新抛出异常的模式:
ExceptionDispatchInfo capturedException = null;
try
{
await SomeWork();
}
catch (Exception e)
{
capturedException = ExceptionDispatchInfo.Capture(e);
}
if (capturedException != null)
{
await FallbackWork();
capturedException.Throw();
}
答案 6 :(得分:1)
您可以使用lambda表达式,如下所示:
try
{
//.....
}
catch (Exception ex)
{
Action<Exception> lambda;
lambda = async (x) =>
{
// await (...);
};
lambda(ex);
}
答案 7 :(得分:0)
您可以将await
放在catch块后跟label
,然后在try块中放置goto
。
(不,真的!后藤不是那么糟糕!)
答案 8 :(得分:0)
在类似的例子中,我无法在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
}