异步函数中的错误处理
本文关键字:错误 处理 函数 异步 | 更新日期: 2023-09-27 17:53:26
我很难弄清楚如何正确处理异步函数中的异常。具有以下代码:
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);
}
}
如何重构它,使其不重复两个函数99%的公共代码?我需要同步和异步地通知一个uri,我不在乎结果,除非我想把它记录下来。
基本上,使用async/await
,您可以遵循与同步编程相同的模式。除非绝对需要,否则不要在每个async
方法内处理异常。在最顶层处理它们,即在最外层的异步或同步方法内部。这个方法是什么取决于执行环境。
例如,如果是UI应用程序,它可能是async void
事件处理程序:
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);
}
}
或者,它可能是控制台应用程序的Main
入口点:
static void Main(string[] args)
{
try {
DoWorkAsync().Wait();
}
catch (Exception ex)
{
// log
logger.Error(ex);
throw; // re-throw to terminate
}
}
您应该了解async
方法的异常是如何传播的。查看此以了解更多详细信息。
此外,并不是所有的例外都是相同的,应该平等处理。查看Eric Lippert的"Vexing例外"。
您应该看看这个问题:使用异步调用时异常处理的良好模式。这可能就是你想要的。
static void NotifyParty(Uri uri, string paramName, string paramValue)
{
await NotifyPartyAsync(uri, paramName, paramValue);
}
或
static void NotifyParty(Uri uri, string paramName, string paramValue)
{
NotifyPartyAsync(uri, paramName, paramValue).Wait();
}
如果您使用的是.net 4.5或4.0,请告诉我。基于此,可能存在一些细微差别。