开发者

Thread pool use in .NET REST service implementation

I am implementing my first REST service in .NET 4 and have encountered something unexpected. It seems that I do not understand the underlining workings of Microsoft's ServiceModel, but could not find the answer in the traditional way.

To implement my web service I was following the steps in this tutorial: http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx

The service works. What surprised me was that Application_BeginRequest and Application_EndRequest in Global.asax are called by different threads. Looking at stack trace it appears that these threa开发者_JAVA百科ds are based in some kind of thread pool.

Without doing some refactorings this is a problem for us since we were always assuming that a single request would always run on the same thread, due to which we were keeping some variables stored in the thread local storage. The variables are initialized in Application_BeginRequest and released in Application_EndRequest. It appears that with ServiceModel this is not the right approach.

My questions are:

  1. Can I make any assumptions about which threads are running my code when I am using ServiceModel?
  2. Is there any way to restrict the execution to a single thread? Would this be bad for any reason?
  3. What is the right way of storing a variable for the duration of request when using ServiceModel?

Thank you.


One thing I'd suggest is to consider using the WCF hooks rather than the Application_BeginRequest and Application_EndRequest methods. Four instance, here are four of the more useful hooks:

AfterReceiveRequest -> BeforeCall -> Method call -> AfterCall -> BeforeSendReply

There hooks are pretty powerful. You an inspect parameters before your method is called (centralize some logging to one place) and do all sorts of other useful things. These are not the only hooks available, there are some others I use as well. For instance GetInstance allows me to override creation of the service class object (so you can use dependency injection frameworks, etc).

When I use the per call concurrency mode, these hooks plus the method call itself ALL get called on the same thread. Hope this helps. I can provide links to implementing these hooks if you like.

Cheers


You may want to look at the [ServiceBehavior] attribute on your service implementation, since it supports arguments to control how many instances get created and what threading model is used.

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

When you have

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

your service will run as a singleton but with multiple threads--up to a threshold set in the WCF config--calling into your methods. To force it to run on only one thread and thereby serialize inbound requests, set ConcurrencyMode.Single.

Alternatively, you could spin up a new instance of your service for each call:

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

The instance will have only one thread accessing it. In fact, when you have InstanceContextMode.PerCall, then the ConcurrencyMode is ignored because it's always "Single", and each instance is running in its own thread.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜