私はこのような実装をしています:
Task<IEnumerable<Item1>> GetItems1()
{
return RunRequest(async () => ParseItemsFromResponse(await(httpClient.Get(..))));
}
Task<IEnumerable<Item2>> GetItems2()
{
return RunRequest(async () => ParseItemsFromResponse(await httpClient.Get(..)));
}
TResult RunRequest<TResult>(Func<TResult> req)
{
try
{
return req();
}
catch (Exception ex)
{
// Parse exception here and throw custom exceptions
}
}
問題は無効な無名メソッドです。async () => ParseItemsFromResponse(..)
。
これはvoidを返し、aを返さないのでTask
匿名メソッド内で例外がスローされても、実際にはそのメソッドによってキャッチされることはありません。try
そしてcatch
以内RunRequest
。
これをリファクタリングする方法がありますか?
RunRequest
取るべきFunc<Task<TResult>>
、 など:
async Task<TResult> RunRequestAsync<TResult>(Func<Task<TResult>> req)
{
try
{
return await req().ConfigureAwait(false);
}
catch (Exception ex)
{
// Parse exception here and throw custom exceptions
}
}
それであなたのasync
ラムダはに変換されますasync Task<T>
の代わりにメソッドasync void
。
私はより多くの情報を持っています同期/非同期デリゲート私のブログに。
ConfigureAwait(false)
?それともコンテキストを元に戻さないことが最適化にすぎないのでしょうか。 - Don Box
async void
。これらは、イベントハンドラ、またはaを受信または処理できない類似のメソッドを対象としています。Task
結果。によってスローされた例外を防ぐことはできませんasync void
アプリケーションの未処理例外ハンドラを除く - Panagiotis KanavosRunRequest
取るTask
の代わりにFunc
そして渡すhttpClient.Get()
直接? - Mats391RunRequest
ParseItemsFromResponseが何かを返さない限り、オーバーロードします。他にもありますかAction
?このようにしないでください。var result=await httpClient.Get();ParseItems(result);
きれいです - Panagiotis Kanavos