class FixedArgumentValidationTwoMethods
{
static void Main()//从同步实现的分开参数验证
{
MainAsync().Wait();
//这里出现异常
}
static async Task MainAsync()
{
Task<int> task = ComputeLengthAsync(null);
// We never get this far, as the exception is thrown eagerly.
Console.WriteLine("Fetched the task");
int length = await task;
Console.WriteLine("Length: {0}", length);
}
static Task<int> ComputeLengthAsync(string text)
{
if (text == null)
{
throw new ArgumentNullException("text");
}
return ComputeLengthAsyncImpl(text);
}
static async Task<int> ComputeLengthAsyncImpl(string text)
{
await Task.Delay(500); // Simulate real asynchronous work
return text.Length;
}
}
可以迫使异常立即抛出。将参数验证和实现分离
就语言形式而言,ComputeLengthAsync本身并不是一个异步方法,因为它没有async
修饰符。该方法执行时使用的是正常的执行流,因此如果方法开始处的验证参数抛出异常,就
真的会抛出异常。如果通过验证,则返回ComputeLengthAsyncImpl方法(工作真正发生
的地方) 创建的任务。更现实的场景中,ComputeLengthAsync可以为公共或内部方法,而
ComputeLengthAsyncImpl应该为私有方法,因为它假设参数验证已经执行过了。
输出
Exception: System.Reflection.TargetInvocationException: 调用的目标发生了异常。 ---> System.AggregateException: 发生一个 或多个错误。 ---> System.ArgumentNullException: 值不能为 null。
参数名: text
在 Chapter15.FixedArgumentValidationTwoMethods.ComputeLengthAsync(String text) 位置 FixedArgumentValidationTwoMethods.cs:行号 28 位置省略
在 Chapter15.FixedArgumentValidationTwoMethods.<MainAsync>d__0.MoveNext() 位置 FixedArgumentValidationTwoMethods.cs:行号 17 位置省略
--- 内部异常堆栈跟踪的结尾 ---
在 System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
在 System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
在 System.Threading.Tasks.Task.Wait()
在 Chapter15.FixedArgumentValidationTwoMethods.Main() 位置 FixedArgumentValidationTwoMethods.cs:行号 12 位置省略
--- 内部异常堆栈跟踪的结尾 ---
在 System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
在 System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
在 MiscUtil.ApplicationChooser.Run(Type type, String[] args)