【发布时间】:2014-02-09 16:14:20
【问题描述】:
在实现返回 Task 以引发异常的方法时,是否有 MS“最佳实践”或合同协议?这是在编写单元测试时出现的,我试图弄清楚我是否应该测试/处理这种情况(我认识到答案可能是“防御性编码”,但我不希望这是答案)。
即
方法必须总是返回一个Task,它应该包含抛出的异常。
方法必须始终返回一个任务,除非方法提供了无效参数(即 ArgumentException)。
方法必须始终返回一个任务,除非开发人员变得流氓并为所欲为 (jk)。
Task Foo1Async(string id){
if(id == null){
throw new ArgumentNullException();
}
// do stuff
}
Task Foo2Async(string id){
if(id == null){
var source = new TaskCompletionSource<bool>();
source.SetException(new ArgumentNullException());
return source.Task;
}
// do stuff
}
Task Bar(string id){
// argument checking
if(id == null) throw new ArgumentNullException("id")
try{
return this.SomeService.GetAsync(id).ContinueWith(t => {
// checking for Fault state here
// pass exception through.
})
}catch(Exception ex){
// handling more Fault state here.
// defensive code.
// return Task with Exception.
var source = new TaskCompletionSource<bool>();
source.SetException(ex);
return source.Task;
}
}
【问题讨论】:
-
有趣的问题。我从未见过这样的指导方针,所以我很想说 4:方法可能会抛出异常或返回包含该异常的任务,调用者应该将这些情况视为等效。
-
@hvd 防御性编码建议调用者处理这两种情况,但我的极简主义者不想处理以多种方式表达的异常。例外是参数检查(有点自相矛盾)。
-
但同时,抛出异常的方式不应取决于该方法是否使用
async实现,因为这是调用者不可见的实现细节。如果您同意这一点,那么这两种情况应该被视为等效,或者您永远不应该同步抛出异常。
标签: c# .net exception task-parallel-library async-await