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财产。