如何记录异步方法的异常?

问题描述 投票:14回答:3

带有XML文档的示例方法:

// summary and param tags are here when you're not looking.
/// <exception cref="ArgumentNullException>
///    <paramref name="text" /> is null.
/// </exception>
public void Write(string text)
{
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    // sync stuff...
}

Write(null)引发异常。这是一个异步方法:

public async Task WriteAsync(string text)
{
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    // async stuff...
}

WriteAsync(null),在等待之前不会引发异常。我是否应该在ArgumentNullException标签中指定exception?我认为这会让消费者认为调用WriteAsync可能会抛出ArgumentNullException并编写如下内容:

Task t;
try
{
    t = foo.WriteAsync(text);
}
catch (ArgumentNullException)
{
    // handling stuff.
}

在异步方法中记录异常的最佳实践是什么?

c# .net asynchronous documentation
3个回答
9
投票

不是一个直接答案,但是我个人建议在这里倾向于快速失败;这可能意味着要编写2种方法:

public Task WriteAsync(string text) // no "async"
{
    // validation
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    return WriteAsyncImpl(text);
}
private async Task WriteAsyncImpl(string text)
{
    // async stuff...
}

此模式也是添加“快速路径”代码的理想位置,例如:

public Task WriteAsync(string text) // no "async"
{
    // validation
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    if (some condition)
        return Task.FromResult(0); // or similar; also returning a pre-existing
                                   // Task instance can be useful

    return WriteAsyncImpl(text);
}

3
投票

Microsoft似乎并没有区分抛出异常的async方法和返回的Task具有存储在其Exception属性中的异常的返回值。例如:

WebClient.DownloadFileTaskAsync(string, string)

我个人会选择将异常记录为返回值(即返回的WebClient.DownloadFileTaskAsync(string, string))的一部分,因为区别对于客户可能很重要。


0
投票

我喜欢您的问题标题,但请考虑修改示例。实际上,您的Task方法将像WriteAsync一样抛出其ArgumentNullException(如果从另一个异步方法调用,应该作为规则)。

事实上,我之前的800次浏览并未引起投诉,恕我直言,您确实应该尝试很好地记录异步方法的异常。

我建议保留异常标记,因为它们会出现在Intellisense中。但是,应该向每个错误条件添加原型化的注释,例如Write(建议更好地表达建议)。

忽略(无论以何种方式)指定这种行为的图书馆作者,如果他们改变了异常是同步引发还是在等待时进行更改,他们可能会在不知不觉中引入重大更改。

© www.soinside.com 2019 - 2024. All rights reserved.