在catch block中等待
我有以下代码:
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下载的exception。 这两个时间当然是asynchronous的。 但是代码不能编译,因为
错误CS1985:不能等待catch子句的正文
好的,不论什么原因都是禁止的,但是这里的代码模式是什么?
编辑:
好消息是C#6.0可能允许在catch和finally块中等待调用 。
更新: C#6.0支持在catch中等待
老答案 :您可以重写该代码以使用标志来移动catch
块的await
:
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" ) );
在catch块中等待,现在可以从Roslyn的最终用户预览中获得,如下所示(在catch / finally中列出)将包含在C#6中。
列出的例子是
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()
结尾)
你可以像下面这样使用lambdaexpression式:
try { //..... } catch (Exception ex) { Action<Exception> lambda; lambda = async (x) => { // await (...); }; lambda(ex); }
在等待回退任务后,我使用该模式重新抛出exception:
ExceptionDispatchInfo capturedException = null; try { await SomeWork(); } catch (Exception e) { capturedException = ExceptionDispatchInfo.Capture(e); } if (capturedException != null) { await FallbackWork(); capturedException.Throw(); }
使用C#6.0。 看到这个链接
public async Task SubmitDataToServer() { try { // Submit Data } catch { await LogExceptionAsync(); } finally { await CloseConnectionAsync(); } }
你可以在catch块之后加上label
,然后在try块中放一个goto
。 (不,真的!后藤的不是那么糟糕!)
在一个类似的例子中,我无法在一个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 }