validation异步方法中的参数
我正在编写一个具有同一方法的同步和异步版本的类void MyMethod(object argument)
和Task MyMethodAsync(object argument)
。 在同步版本中,我通过简单检查validation参数
if (argument == null) throw new ArgumentNullException("argument");
在异步方法中,相同的检查应该如何?
1)与同步方法相同
2)(第一次回答后更新)
if (argument == null) return new Task.Factory.StartNew(() => { throw new ArgumentNullException("argument"); });
这取决于你何时想要提出错误 – 即急切地,或作为等待的一部分。 与迭代器块一样,如果您需要急切的错误检查,则需要两种方法,例如:
public Task SomeMethod(..args..) { if(..args fail..) throw new InvalidOperationException(...); return SomeMethodImpl(...args...); } private async Task SomeMethodImpl(...args...) { ... await etc ... }
然后,这将作为初始调用的一部分执行任何参数检查,而不是等待。 如果你希望exception成为等待的一部分,你可以抛出它:
public async Task SomeMethod(..args..) { if(..args fail..) throw new InvalidOperationException(...); ... await etc ... }
但是,在您的示例中,您return
Task
的事实表明这实际上不是async
方法,而是异步 (但不是async
)方法。 你不能只做:
return new Task(() => { throw new ArgumentNullException("argument"); });
因为该Task
永远不会开始 – 而且永远不会。 我怀疑你需要做类似的事情:
try { throw new InvalidArgumentException(...); // need to throw to get stacktrace } catch(Exception ex) { var source = new TaskCompletionSource(); source.SetException(ex); return source.Task; }
这是……有点拗口,可能会被封装好一点。 这将返回一个Task
,指示它处于Faulted
状态。
简单地像在sync方法中那样抛出它,TPL有各种机制来重新抛出exception,例如当你阅读时。 Result
属性或访问权限。 Exception
财产。