Await in catch block
Solution 1
Update: C# 6.0 supports await in catch
Old Answer: You can rewrite that code to move the await
from the catch
block using a flag:
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" ) );
Solution 2
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.
The example listed is
try … catch { await … } finally { await … }
Update: Added newer link, and that it will be in C# 6
Solution 3
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;
Solution 4
Give this a try:
try
{
await AsyncFunction(...);
}
catch(Exception ex)
{
Utilities.LogExceptionToFile(ex).Wait();
//instead of "await Utilities.LogExceptionToFile(ex);"
}
(See the Wait()
ending)
Solution 5
Use C# 6.0. see this Link
public async Task SubmitDataToServer()
{
try
{
// Submit Data
}
catch
{
await LogExceptionAsync();
}
finally
{
await CloseConnectionAsync();
}
}
Related videos on Youtube
György Balássy
György Balássy is working as a Principal Engineer on LogMeIn’s next generation Internet of Things (IoT) cloud platform. Before joining LogMeIn, he has been teaching web technologies and techniques on the Budapest University of Technology and Economics. He is a founding member of the local MSDN Competence Centre having important role in evangelizing the .NET platform as a speaker, book author and consultant. György provided leadership in the foundation of the Hungarian .NET community as a key evangelist on Microsoft events, technical forums and as the head of the Portal Technology Group in the MSDNCC. He is a regular speaker on community and industrial events presenting in-depth technical sessions on .NET, ASP.NET, Office development and ethical hacking, with which he won the Best Speaker and the Most Valuable Professional Awards in SharePoint, ASP.NET and IIS in every years since 2004, and was selected to be the member of the ASPInsiders group. Between 2005 and 2015 György has been the Microsoft Regional Director in Hungary.
Updated on July 08, 2022Comments
-
György Balássy almost 2 years
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
error CS1985: Cannot await in the body of a catch clause
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.
-
György Balássy over 12 yearsThanks svick, that's quite obvious, anything better, more connected to async?
-
svick over 12 yearsI don't think anything like that exists.
-
Stephen Cleary over 12 yearsIn your case, you could also use task continuations. But the code in
svick
's answer is cleaner than code using continuations. -
Etienne Maheu over 9 yearsIf you even need to rethrow the exception without loosing the callstack, you can also use the
System.Runtime.ExceptionServices.ExceptionDispatchInfo
static class. Simply callExceptionDispatchInfo.Capture(ex)
in your catch block and store the return value, the captured exception, in a local variable. Once you're done with your async code, you can usecapturedException.Throw()
which will properly rethrow the original exception. -
Zia Ur Rahman almost 7 yearsawesome technique
-
Tim Lovell-Smith over 6 yearsAnd what VS version is that in? Answer: C# 6 is in the box in Visual Studio 2015 (and its preview).
-
svick over 6 yearsThis makes the lambda
async void
, which should not be used, unless you have to.