2015-10-26 4 views
6

ASP.NETは、「スレッドの敏捷性」と呼ばれるものを示すことが知られています。要するに、一度に1つ以上のスレッドではありませんが、単一の要求を満たすために複数のスレッドを使用することができます。これは、非同期I/Oを待機しているスレッドがプールに戻って他の要求を処理するために使用されることを意味する最適化です。ASP.NETスレッドの俊敏性 - どのように克服するのですか?

ただし、ASP.NETは要求を移動するときにスレッド関連のデータをすべて移行しません。 Microsoftはこれを忘れてしまったのですが、ThreadStatic属性で簡単に作成できるスレッドローカルストレージを使用することは、ASP.NET自体をコーディングする人のみが行うべきことだと考えていました。

すごくグーグルに基づいて、この問題を回避する唯一の方法は、代わりにHttpContextに依存することです。 ASP.NETが実際に移行されるのは、ASP.NETが要求の途中でスレッドを切り替えることを決定しているため、これが問題を克服しているからです。しかし、これはまったく新しい頭痛を引き起こします。アプリケーションロジックをHttpContextに結びつけ、したがってWebコンテキストに結び付けます。それはすべての状況で受け入れられるものではありません(実際には、ほとんどの場合、受け入れられません)。また、HttpContextはシールされており、内部コンストラクタを持っているので、モックやスタブすることはできません。したがって、ロジックもテストできなくなります。

this (old) blog postによれば、CallContextは機能しません。これは、コールコンテキストが概念的には正確に論理スレッドであることを考えるとかなり威嚇的です!

asp.netコンテキストだけでなく他のコンテキストでも動作する "LOGICALスレッドごとの"分離を確実に実装する簡単な方法はありますか?

もしそうでなければ、問題を解決する軽量のサードパーティフレームワークを知っている人はいますか? ASP.NETがスレッドを移行するときにStructureMapが正しく動作しますか?

私は一般的な答えをお伝えしたいと思いますが、私が見ている具体的な使用例は、SharePointのコンテキストでのEntity Frameworkの使用です。残念ながら、しばらくの間SP-2010とEF 3.5に悩まされています。 EFでは、基本的には、最初に読みとったのと同じコンテキストでデータを保存する必要があります。そうでない場合は、自分で変更を追跡する必要があります。 「現行モデル」のコンセプトを紹介したいと思います。最初に、各HTTP要求を処理する際にモデルが呼び出されたときには、そのモデルをインスタンス化してから、同じモデルインスタンスを要求の期間使用する必要があります。しかし、 "Model.Current"に依存するコードはでもはタイマジョブのコンテキストで実行されるべきです。私は、タイマーのジョブコードを使ってモデルを明示的に破棄しても問題ありません(SharePoint WebコンテキストのHttpApplication.EndRequestのハンドラに与えたい作業です)。

これをやっていない理由があるかもしれませんが、それも面白いですが、とにかくは、asp.netコンテキストで "論理スレッド分離"を達成する方法を学ぶことに本当に感謝しています。非常に便利です。

+0

あなたはasp.netの非同期ハンドラについて話しています。デフォルトでasp.netは**非同期**ではないため、すべての要求は単一のブロックI/Oスレッドによって処理されます。非同期ハンドラの場合は、独自の 'IWhateverContext'インタフェースを宣言し、HttpContextからロジックを切り離したい場合は、実装クラスによってHttpContextをラップすることができます。 –

+0

いいえ、私はプレーンバニラasp.netコードについて話しています。多くの.NET Frameworkコードでは、非同期I/Oを使用しています(これは素晴らしい)。新しいスレッドに移行する要求は、通常のasp.netアプリケーションで発生する可能性があります。*すべてのスレッドのアスペクト正しく移行されていたので、それは透明であり、ランダムに物を壊さなかった)。 –

+0

Btw、* wrapping * HttpContextとのデカップルはどうですか?依存関係はそこに残っていて、モバイルアプリケーション、Windowsフォーム、WPFアプリなどで同じビジネスレイヤーを使用していた場合は、タイマージョブなど、現在のHttpContextが存在しなくてもクラッシュします。 –

答えて

0

問題に関連する良い投稿があります:Implicit Async Context ("AsyncLocal")私はすべての権利を得た場合

は、論理CallContextすなわちCallContext.LogicalGetDataCallContext.LogicalSetDataが正しくあなたは.NET 4.5過ぎて世界に住んで与えられた不変のデータを移行することが本当作ります。これはimmutable制限はナットですがまだまだ...行く方法。

関連する問題