Thread pool use in .NET REST service implementation - c#

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 threads 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:
Can I make any assumptions about which threads are running my code when I am using ServiceModel?
Is there any way to restrict the execution to a single thread? Would this be bad for any reason?
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.

Related

Is there a way to scope lifetime in .NET DI to a thread, including child threads?

To enforce authorization in my applications, I usually decorate every domain service with an authorization decorator, that takes some service authorizer to perform authorization.
For instance: CarService : ICarService is decorated with CarServiceAuthorizationDecorator : ICarService that gets an ICarServiceAuthorizer injected to perform authorization and when successfull, calls the actual CarService.
This setup has served me well, except one little detail that has always bugged me: I have to pass some Token with every single call to ICarService, because the authorizer needs it. Even if it doesn't, then the CarService may call a CarOwnerShipService that is again decorated with an authorizer, that may need it as well. A lot of Tokens everywhere.
The only way that I can come up with, to fix this, is to inject some ITokenProvider into the CarServiceAuthorizer that acts like a storage device: You put in the token at the start, and it keeps it along the way for any service that gets it out, so it doesn't need to be passed with every method call.
For this to work, the lifetime of that ITokenProvider must be the same as the lifetime of the thread. And not only that: newly spawned threads will need the token too.
So my question is: Is there a way to scope the lifetime of my ITokenProvider to a thread, including child threads, in .NET DI?
(AddScoped doesn't seem to help me, I think, because not all threads in my application start with a web request. Also, I have had major issues with newly spawned threads with AddScoped, that would lose their state.)
that acts like a storage device: You put in the token at the start, and it keeps it along the way for any service that gets it out, so it doesn't need to be passed with every method call.
AddScoped doesn't seem to help me, I think, because not all threads in my application start with a web request.
Based on the first quote I would argue that scoped ITokenProvider is exactly what you need (though without seeing the actual code it is more of a guess). Just create a scope when needed and use it, and do not rely on threading (i.e. you can spawn several threads using the same scope). Something along this lines:
IServiceProvider serviceProvider = ...;
using (var serviceScope = serviceProvider.CreateScope())
{
var tokenService = serviceProvider.GetRequiredService<ITokenProvider>(); // or even split `ITokenProvider` into two interfaces
tokenService.SetToken("");
// resolve and call something using the token somewhere down the pipeline ...
// Maybe even with Task.Run(...)
}

ASP.NET Core pipeline multithreading

Does ASP.NET Core pipeline handle requests by multithreading?
If it does, how do you configure the number of threads? And also, should singleton services be thread safe?
The first question was already answered in the comment above (look into KestrelServerOptions)
Regarding thread safetly, the answer is in the documentation:
Singleton lifetime services are created the first time they are requested (or when ConfigureServices is run if you specify an instance there) and then every subsequent request will use the same instance. If your application requires singleton behavior, allowing the services container to manage the service's lifetime is recommended instead of implementing the singleton design pattern and managing your object's lifetime in the class yourself.
That means all requests for the service pull the same object, which means no per-thread objects, and thus no thread safety.
Thread safety
Singleton services need to be thread safe. If a singleton service has a dependency on a transient service, the transient service may also need to be thread safe depending how it’s used by the singleton.
Coudn't be more clear. Since the objects are not created per thread, they are not thread safe by default (though it's possible some services are designed to be).

Pass data using ThreadLocal<T> across different classes

Edited my Question with more info below regarding the "another thread" after usr pointed out that my question wasn't clear.
How can I pass data using the ThreadLocal<T> across different classes?
Basically, I need to pass the LogContext info from a class in the Webservice to a TraceExtension:SoapExtension class (The TraceExtension is to log request/responses of another WebService that this WebService calls).
Since the functionality runs on another thread and not the thread that initiated the request, I cannot get it from a ServiceContext:IExtension <InstanceContext>
, that I would normally use for such a thing.
I have a working implementation using the Thread.GetNamedDataSlot() way, but in performance testing we found there is a memory leak problem. (Yes, I have called the Thread.FreeNamedDataSlot() and the problem persisted). This lead to MS post http://support.microsoft.com/kb/2540745 that a leak problem may exist, but in our current timeframe for the release it will not be possible to deploy the fix on all the production servers. The work around suggested is to use the System.Threading.ThreadLocal class.
All the resources/examples I have found so far have instances of ThreadLocal in the same class and of Parallelism and PLinq. An example of initializing/setting data in one class and retrieving it from another will be very helpful.
Any other way of passing data to the TraceExtension : SoapExtension will also be equally helpful.
We are a bit tight on schedule and any help will be much appreciated.
Edit with more info:
The thread of our Webservice on which the request comes creates a new Thread on which we run some background processing, while returning the necessary response.
The new Thread invokes calls to other backend web services. We also have a TraceExtension class to trace the Request/Response to the backend web serivces.
We pass the LogContext info from the original Thread to the method on the new Thread using a ContextInfo : ISynchronizeInvoke.
The problem is getting the LogContext object From the class invoking the backend webservice call To the TraceExtension class (which runs on the new Thread and not the original Thread on which the client request came having the ServiceContext:IExtension<InstanceContext> which does hold the LogContext)
You want the ThreadStaticAttribute.

Detect Idle in Windows Service

I have a windows service that will be started(remotly) when it is called. I dont want to keep service running so I want the service be self-stopped when enter in idle time, means few minutes after the last call.
I dont want to stop the service from my remote client because I dont know if I finish to work with, that's why I want to use some Idle event in service side.
There is some way ?
thanks,
Add a timer in the Windows Service which is reset on each call. When the timer elapses (some number of minutes later) have it call the service's Stop method, effectively stopping the server once it becomes idle.
Additional Info
In order to reduce your coding overhead you're looking for an intercept point to handle this timer. If you're using WCF for your service calls the simplest way to do that is with a custom IParameterInspector added as a service extension. You can add the timer logic into the AfterCall() method so that every service call runs through this same block of code & resets the timer. See this MSDN article for details on implemnting custom behaviors.
If you aren't using WCF it's a little trickier. You could use an AOP framework like Castle Windsor or PostSharp, or design your service in a message passing style. AOP allows you to decorate your methods with a property that will call your reset code. Message passing involves desigining your service's contract such that there is a single generic entry point into the service which inspects the incomping message & routes it to the correct method based on it's contents. As you can imagine, one entry point = one place to add the timer reset code. But neither of these are as clean or easy to implement as the WCF-based solution IMO.

Do I need to dispose a web service reference in ASP.NET?

Does the garbage collector clean up web service references or do I need to call dispose on the service reference after I'm finished calling whatever method I call?
Instead of worrying about disposing your web services, you could keep only a single instance of each web service, using a singleton pattern. Web services are stateless, so they can safely be shared between connections and threads on a web server.
Here is an example of a Web Service class you can use to hold references to your web service instances. This singleton is lazy and thread-safe. It is advised that if you make your singletons lazy, they are also kept thread safe by following the same logic. To learn more about how to do this, read the C# In Depth article on Implementing Singletons.
Also keep in mind that you may run into issues with WCF web services. I'd recommend reading up on WCF's instance management techniques article, specifically the singleton section, for more details.
public static class WS
{
private static object sync = new object();
private static MyWebService _MyWebServiceInstance;
public static MyWebService MyWebServiceInstance
{
get
{
if (_MyWebServiceInstance == null)
{
lock (sync)
{
if (_MyWebServiceInstance == null)
{
_MyWebServiceInstance= new MyWebService();
}
}
}
return _MyWebServiceInstance;
}
}
}
And then when you need to access your web service, you can do this:
WS.MyWebServiceInstance.MyMethod(...)
or
var ws = WS.MyWebServiceInstance;
ws.MyMethod(...)
I've successfully used this pattern on several projects and it has worked well, but as tvanfosson mentions in the comments below, an even better strategy would be to use a DI framework to manage your web service instances.
I think the DataService inherits Dispose from Component.
Objects that implement IDispose should be disposed of manually to assist the garbage collector.
If you object is short lived use a using block. For objects that can be retained ensure that they object that retains them disposes of them when it is also disposed.
what are you trying to accomplish here?
If your worried about performance, then I would worry more about the responsiveness of the server hosting the webservice and the network speed, as they can dramatically affect the length of time you have to wait for the webservice call to complete (unless its asynchronous).
The examples on MSDN dont call 'Dispose' and its quite obvious that the garbage collector will do its job, so unless your working on a realtime system that needs to process over 100,000 records in memory every second, then maybe you dont need to come up with a way to dispose resources or manage memory.
I think the concerns of Seabizkit in the above answer are very legitimate.
It's quoted here:
#DanHerbert what happens when two threads call the singleton.. let me explain... there is a lock on the object.. to make it thread safe. Does that mean that if theard1 call accesses webInstance, then thread2 will wait on thread1 to finish. or is the lock purely for the creatation of the instance. say you have 10 callers.... does the lock mean they are chained... or async, i think you will get what I'm asking let me know if it wasn't clear. – Seabizkit Oct 13 '16 at 10:01
<
After I've done some testing I can tell that you won't be able to get any good performance when a single 'client' object is used by multiple different threads.
If ten threads are created and they all are using the same singleton 'client' then they will have to wait in line until all previous calls are done.
To see the proof for that please read and run a sample in this c-sharp corner article here:
https://www.c-sharpcorner.com/article/increase-performance-with-an-object-pool-or-why-singleton-may-cause-performance/
titled "Increase Performance with an Object Pool or Why Singleton May Cause Performance Issues".
Sorry to burst the bubble of the singleton web service users. Also, you would be very hard-pressed to find Microsoft's example where the web service client is "caged" in the singleton.

Categories

Resources