简体   繁体   English

异步功能内的错误处理

[英]Error handling within async function

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? 我如何重构它以不重复两个函数共有的99%代码? I need to notify an uri both synchronously and asynchronously and I don't care about the result except I want it logged. 我需要同时和异步通知uri,除了要记录日志,我不在乎结果。

You should look at this question: Good pattern for exception handling when using async calls . 您应该查看以下问题: 使用异步调用时异常处理的良好模式 It might be what you're looking for. 这可能是您要寻找的。

Basically, with async/await you can follow the same pattern you do for synchronous programming. 基本上,使用async/await可以遵循与同步编程相同的模式。 Don't handle exceptions inside every async method, unless absolutely required. 除非绝对必要,否则不要在每个 async方法中处理异常。 Handle them on the topmost level, ie, inside the outermost async or synchronous method. 在最顶层(即最外部的异步或同步方法)内处理它们。 What's this method is depends on the execution environment. 这个方法是什么取决于执行环境。

Eg, it might be an async void event handler in case it's a UI app: 例如,如果是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);
    }
}

Or, it may be the Main entry point of a console app: 或者,它可能是控制台应用程序的Main入口点:

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. 您应该了解async方法如何传播异常。 Check this for some more details. 检查以获取更多详细信息。

Also, not all exceptions are the same and should be handled equally. 另外,并非所有例外都相同,因此应平等对待。 Check Eric Lippert's "Vexing exceptions" . 检查Eric Lippert的“烦恼例外”

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. 让我知道您是否正在使用.net 4.5或4.0。 there may be some nuances based on that. 在此基础上可能会有一些细微差别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM