等待接球
本文关键字:等待 | 更新日期: 2023-09-27 18:20:15
我有以下代码:
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可能会允许catch和finally块中的等待调用。
更新:C#6.0支持捕获中的等待
旧答案:您可以重写该代码,使用标志将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" ) );
从Roslyn的最终用户预览开始,现在可以在catch块中等待,如下所示(在catch/finally中的Await下列出),并将包含在C#中。
列举的例子是
try … catch { await … } finally { await … }
更新:添加了更新的链接,它将在C#6 中
这似乎有效。
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;
尝试一下:
try
{
await AsyncFunction(...);
}
catch(Exception ex)
{
Utilities.LogExceptionToFile(ex).Wait();
//instead of "await Utilities.LogExceptionToFile(ex);"
}
(参见Wait()
结尾)
使用C#6.0。请参阅此链接
public async Task SubmitDataToServer()
{
try
{
// Submit Data
}
catch
{
await LogExceptionAsync();
}
finally
{
await CloseConnectionAsync();
}
}
您可以将await
放在catch块之后,然后放一个label
,并将goto
放在try块中。(不,真的!后藤没有那么糟糕!)
在等待回退任务后,我用来重新抛出异常的模式:
ExceptionDispatchInfo capturedException = null;
try
{
await SomeWork();
}
catch (Exception e)
{
capturedException = ExceptionDispatchInfo.Capture(e);
}
if (capturedException != null)
{
await FallbackWork();
capturedException.Throw();
}
您可以使用如下lambda表达式:
try
{
//.....
}
catch (Exception ex)
{
Action<Exception> lambda;
lambda = async (x) =>
{
// await (...);
};
lambda(ex);
}
在类似的例子中,我无法在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
}