异步函数中的错误处理

时间:2014-03-25 07:03:31

标签: c# asynchronous exception-handling error-handling c#-5.0

我很难弄清楚如何正确处理异步函数中的异常。拥有以下代码:

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,我不关心结果,除非我想记录它。

3 个答案:

答案 0 :(得分:1)

你应该看看这个问题:Good pattern for exception handling when using async calls。这可能是你正在寻找的东西。

答案 1 :(得分:1)

基本上,使用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方法传播异常。请查看this了解更多详情。

此外,并非所有例外都是相同的,应该平等对待。检查Eric Lippert的"Vexing exceptions"

答案 2 :(得分:0)

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();
}

如果您使用的是.net 4.5或4.0,请与我们联系。基于此可能存在一些细微差别。