5

Web サービスに大きく依存する Web アプリケーションがあります。サービスに関するすべての処理は、AddOnPreRequestHandlerExecuteAsync を使用して非同期で行われます。とにかく、ほとんどの呼び出しは問題なく動作しますが、非同期サービス呼び出しから戻って endprerequest で null の HttpContext.Current.Response/Request オブジェクトを見つけるものもあります。両方のオブジェクト (Response と Request は、失敗した呼び出しの beginprerequest で利用可能/null ではなく、他の呼び出しの endprerequest で機能します)。

誰かが同様に遭遇したり、問題が何であるかについて推測したりしますか?

更新:解決策を見つけたようです.Init(これがすべて発生するHttpModuleの)でHttpApplicationの変数を作成すると、その変数からHttpContextにアクセスできます。

更新: begin 関数で HttpApplication または HttpContext.Current を渡すと、同じ問題が発生します。非同期呼び出しの「状態」の一部として渡されると、begin 関数では有効であっても、end 関数では null になります。

更新: ログを追加したところ、作成している非同期呼び出しが正しく返され、結果が存在し、コールバック関数が適切に呼び出されていることがわかりました。

4

2 に答える 2

5

私はあなたが直面している問題を知っていると思います。答えは、ほぼ確実に、の使用法をに置き換えHttpWebRequestWebClientの*Asyncメソッドを使用することですWebClient

長い説明は次のとおりです。IAsyncResult非同期パターンイベントベースの非同期パターンの2つのまったく異なる非同期プログラミングモデルがあります。IAsyncResultパターンはBeginXXXEndXXXメソッドを使用し、IAsyncResultインスタンスを使用し、コールバックにデリゲートを使用し、完了の待機をサポートします。イベントベースのパターンは、XXXAsyncメソッドを使用して非同期アクションを開始しXXXCompleted、コールバックの代わりにイベントを使用して完了を処理し、(これはあなたの場合に重要です)スレッド固有のコンテキストをすべてのコールバックイベントハンドラーに転送します。

つまり、コールバックコードをXXXCompletedイベントハンドラー(などWebClient.DownloadStringCompleted)内に配置すると、HttpContext.Currentが正しく入力されます。

ただし、BeginXXXメソッド(などHttpWebRequest.BeginGetResponse)とデリゲートコールバックを使用する場合、コールバックは、適切なASP.NETコンテキストがアタッチされていることを保証しないスレッドのコンテキストで実行されます。

一般に、.NET Frameworkライブラリクラスは、いずれかの非同期パターンを使用します。通常、下位レベルのクラス(eg HttpWebRequest)はIAsyncResultパターンを使用し、上位レベルのクラス(eg WebClient)はイベントベースのパターンを使用します。一部の奇妙なクラス(自動生成された.NET Remotingプロキシなど)は両方のパターンをサポートしますが、それはまれです。

したがって、簡単に実行できる場合は、HttpWebRequestおよびコールバックデリゲートではなく、WebClientおよびイベントハンドラーに移行することをお勧めします。これで問題が解決するはずです。WebClientへの切り替えが難しすぎる場合は、コメントしてください。おそらく、もっとわかりにくい代替案を提案できます。

于 2009-12-27T01:33:04.497 に答える
0

解決策を見つけたようです。Init で HttpApplication の変数を作成すると (これがすべて発生する HttpModule の)、その変数から HttpContext にアクセスできます。

于 2010-01-05T16:45:11.557 に答える