それは、いつエラーを発生させたいかによって少し異なります-つまり、熱心に、または awaitable の一部として。イテレータ ブロックと同様に、熱心なエラー チェックが必要な場合は、次のような 2 つのメソッドが必要です。
public Task<int> SomeMethod(..args..) {
if(..args fail..) throw new InvalidOperationException(...);
return SomeMethodImpl(...args...);
}
private async Task<int> SomeMethodImpl(...args...)
{
... await etc ...
}
これにより、awaitable ではなく、最初の呼び出しの一部として引数チェックが実行されます。例外を awaitable の一部にしたい場合は、それをスローできます。
public async Task<int> 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<int>();
source.SetException(ex);
return source.Task;
}
これは... 少し一口で、おそらくもう少しうまくカプセル化できます。Task
これは、状態にあることを示すa を返しFaulted
ます。