4

svcutilによって生成されたプロキシを使用していくつかのWCFサービスを呼び出すAsp.Netアプリケーションがあります。生成されたプロキシには、APMパターン(BeginXxx、EndXxx)の非同期メソッドがあります。

新しいパターンを活用するために非同期ターゲティングパックを使用していasync/awaitます。ターゲットプラットフォームは.net4.0です(それ以外の場合は、非同期ターゲティングパックを使用する必要はありません)。

Task<T>.Factory.FromAsyncAPMパターンを待機可能なタスクに変換するために使用しています。

私のコードは少しそのように見えます(サービスメソッドがパラメータを受け取らず、intを返すと仮定します:

int result = await Task<int>.Factory.FromAsync(proxy.BeginXxx, proxy.EndXxx, state: null);
HttpContext.Current.Items["reuslt"] = result;

2行目は。をスローしNullReferenceExceptionます。

その理由は、コールバック(await呼び出しの後に実行されるすべてのもの)に元の同期コンテキストがないためだと思います。

他のメソッド(Factory.StartNewなど)には、コンテキストを保持するために使用できるを受け取るオーバーロードがあります。TaskScheduler

FromAsyncメソッドには、を受け取るオーバーロードTaskSchedulerもありますが、引数としてbeginメソッドを持っているものはありません。

この行の後に呼び出されるすべてのメソッドへのメソッド引数としてHttpコンテキストを手動で渡し始めたくないと仮定すると、タスクスケジューラを取得するオーバーロードを使用するか、同期コンテキストを尊重するために.Netを取得するにはどうすればよいですか?

4

1 に答える 1

5

問題は実際には ASP.NET パイプラインではなく、SynchronizationContext.

Async Targeting Pack はasync/awaitサポートを有効にしますが、ASP.NET 4.5 には フレンドリーにするために多くの変更が加えられてasyncおり、Targeting Pack にはそのサポートが含まれていません。

RegisterAsyncTask(Web フォームの場合) またはAsyncManager(MVC の場合)を使用して、ASP.NET パイプラインを支援してみてください。それでも、パイプラインには非同期コードを使用できない場所がいくつかあります (ASP.NET 4.5 でも同様ですが、少なくとも 4.5 ではこれが検出され、エラーがスローされます)。

于 2012-08-19T19:40:29.983 に答える