如何记录异步方法的异常
本文关键字:异步方法 异常 记录 何记录 | 更新日期: 2023-09-27 18:08:19
带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)
,在等待之前不会抛出异常。我应该在exception
标签中指定ArgumentNullException
吗?我认为这将使消费者认为调用WriteAsync
可能会抛出ArgumentNullException
,并编写如下内容:
Task t;
try
{
t = foo.WriteAsync(text);
}
catch (ArgumentNullException)
{
// handling stuff.
}
在异步方法中记录异常的最佳实践是什么?
不是一个直接的答案,但我个人建议在这里倾向于快速失败;这可能意味着要写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);
}
Microsoft似乎没有区分抛出异常的async
方法和返回的Task
在其Exception
属性中存储异常之间的区别。例如:
WebClient.DownloadFileTaskAsync(string, string)
就我个人而言,我会选择将异常记录为返回值(即返回的Task
)文档的一部分,因为这种区别对客户端可能很重要。
我建议保留异常标记,因为它们在智能感知中显示。
为简洁起见,我不会提及异常是否快速失败,只要这符合直觉。也就是说,完整性检查应该快速失败,而在执行过程中不应该失败。如果你必须偏离此规则,请将其记录下来。
请注意,更改异常是同步抛出(快速失败)还是等待可能会破坏客户代码。