2011-01-05 16 views
7

私は.NET 4で最初のRESTサービスを実装していて、予期せぬものに遭遇しました。私はMicrosoftのServiceModelの基本的な動作を理解していないようですが、伝統的な方法で答えを見つけることはできませんでした。 http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx.NET RESTサービスの実装でのスレッドプールの使用

サービス作品:私はこのチュートリアルの手順に従っていました私のWebサービスを実装するために

。私が驚いたことは、Global.asaxのApplication_BeginRequestとApplication_EndRequestが別のスレッドによって呼び出されたことです。スタックトレースを見ると、これらのスレッドは何らかの種類のスレッドプールに基づいているようです。

いくつかの変数をスレッドローカルストレージに保存していたため、常に同じスレッドで1つのリクエストが常に実行されると仮定していたため、これは問題でした。変数はApplication_BeginRequestで初期化され、Application_EndRequestで解放されます。 ServiceModelでは、これは正しいアプローチではないようです。

私の質問は以下のとおりです。

  1. は、私はServiceModelを使用していたときにスレッドが私のコードを実行されているかについて何らかの仮定を行うことができますか?
  2. 実行をシングルスレッドに制限する方法はありますか?これは何らかの理由で悪いことでしょうか?
  3. ServiceModelを使用しているときに、要求期間中変数を格納する正しい方法は何ですか?

ありがとうございます。

+0

最新の質問に更新します。その1つのスレッドはApplication_BeginRequestを呼び出し、別のスレッドはサービスコードを実行してApplication_EndRequestを実行します。 ServiceBehaviorの変更は何もしませんでした。どんな助けでも大歓迎です。 – Alex

+0

あなたはasp.net互換性のものを使用しているように聞こえます。メッセージディスパッチャ、または他のwcf拡張ポイントとして(asp.netを使用する代わりに)あなたのものを実装しようとしましたか? – sisve

+0

@Simon Svensson私はMicrosoftのチュートリアルhttp://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspxに従っていました。これは、asp.netとの互換性を使用するように見えます。他のアプローチを使用すると、何が違うでしょうか?私が読むことができる良い場所はありますか?ありがとう! – Alex

答えて

0

サービス実装の[ServiceBehavior]属性は、作成されるインスタンスの数と使用されるスレッドモデルを制御する引数をサポートしている場合があります。

http://msdn.microsoft.com/en-us/library/cc681240.aspx

あなたは

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
       ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class MyService : IMyService 

を持っている場合は、あなたのサービスはシングルトンとしてではなく、複数のスレッドで実行されます - WCFの設定で設定した閾値まで - あなたのメソッドを呼び出します。これを強制的に1つのスレッドのみで実行し、のインバウンド要求をシリアル化するには、ConcurrencyMode.Singleを設定します。

また、あなたはそれぞれの呼び出しについては、サービスの新しいインスタンスをスピンアップすることができます:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
       ConcurrencyMode = ConcurrencyMode.Single)] 
public class MyService : IMyService 

インスタンスは、それをアクセスするスレッドを1つだけ持っています。実際、InstanceContextMode.PerCallを持つ場合、ConcurrencyModeは常に「Single」であり、各インスタンスはそれぞれのスレッドで実行されているため、無視されます。

+0

ありがとうローレンス。 Iは[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall、 ConcurrencyMode = ConcurrencyMode.Single)] まだ( Thread.CurrentThread.GetHashCodeを呼び出す) を設定した。ToStringメソッド()Application_BeginRequestとApplication_EndRequestに が異なる返し値は、私は間違って何かをしていますか? – Alex

2

私が示唆していることの1つは、Application_BeginRequestメソッドとApplication_EndRequestメソッドではなく、WCFフックの使用を検討することです。ここでは四例えば、より便利なフックの4です:

AfterReceiveRequest - > BeforeCall - >メソッドの呼び出し - > AfterCall - > BeforeSendReply

ありフックはかなり強力です。メソッドが呼び出される前にパラメータを検査して(一部のログを1か所に集約して)、他の有用なものをすべて実行します。これらは利用可能な唯一のフックではありません、私も同様に使用するいくつかの他のものがあります。たとえば、GetInstanceではサービスクラスオブジェクトの作成をオーバーライドできます(依存関係注入フレームワークなどを使用できます)。

呼び出しごとの並行性モードを使用すると、これらのフックとメソッド呼び出し自体が同じスレッドで呼び出されます。お役に立てれば。私はあなたが好きなら、これらのフックを実装するためのリンクを提供することができます。

乾杯

関連する問題