Reputation: 15179
I'm having hard time trying to figure out how to properly handle exceptions within async functions. Having the following code:
static async Task NotifyPartyAsync(Uri uri, string paramName, string paramValue)
{
string link = string.Format("{0}?{1}={2}", uri, paramName, HttpUtility.UrlEncode(paramValue));
using (var client = new HttpClient())
try {
using (HttpResponseMessage response = await client.GetAsync(link, HttpCompletionOption.ResponseHeadersRead))
logger.DebugFormat("HTTP {0} from {1}", (int)response.StatusCode, link);
}
catch (Exception ex) {
logger.Error(ex);
}
}
static void NotifyParty(Uri uri, string paramName, string paramValue)
{
string link = string.Format("{0}?{1}={2}", uri, paramName, HttpUtility.UrlEncode(paramValue));
using (var client = new HttpClient())
try {
using (HttpResponseMessage response = client.GetAsync(link, HttpCompletionOption.ResponseHeadersRead).Result)
logger.DebugFormat("HTTP {0} from {1}", (int)response.StatusCode, link);
}
catch (Exception ex) {
logger.Error(ex);
}
}
How do I refactor it to not repeat 99% code common to both functions? I need to notify an uri both synchronously and asynchronously and I don't care about the result except I want it logged.
Upvotes: 1
Views: 1838
Reputation: 61744
Basically, with async/await
you can follow the same pattern you do for synchronous programming. Don't handle exceptions inside every async
method, unless absolutely required. Handle them on the topmost level, i.e., inside the outermost async or synchronous method. What's this method is depends on the execution environment.
E.g., it might be an async void
event handler in case it's a UI app:
async Task DoWorkAsync()
{
// don't handle exceptions here
}
async void Form_Load(object s, EventArgs args)
{
try {
await DoWorkAsync();
}
catch (Exception ex)
{
// log
logger.Error(ex);
// report
MessageBox.Show(ex.Message);
}
}
Or, it may be the Main
entry point of a console app:
static void Main(string[] args)
{
try {
DoWorkAsync().Wait();
}
catch (Exception ex)
{
// log
logger.Error(ex);
throw; // re-throw to terminate
}
}
You should understand though how exceptions get propagated for async
methods. Check this for some more details.
Also, not all exceptions are the same and should be handled equally. Check Eric Lippert's "Vexing exceptions".
Upvotes: 1
Reputation: 8877
You should look at this question: Good pattern for exception handling when using async calls. It might be what you're looking for.
Upvotes: 1
Reputation: 9499
static void NotifyParty(Uri uri, string paramName, string paramValue)
{
await NotifyPartyAsync(uri, paramName, paramValue);
}
OR
static void NotifyParty(Uri uri, string paramName, string paramValue)
{
NotifyPartyAsync(uri, paramName, paramValue).Wait();
}
let me know if you're working with .net 4.5 or 4.0. there may be some nuances based on that.
Upvotes: 0