ASP.NET Core pipeline multithreading - c#

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).

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(...)
}

constructor injection & Factories: Object required in two types of life times?

I have a situation where I have an object C that is required by two types of classes. One of these class runs in separate thread, the other one creates multiple threads with the help of timer elapsed event.
So there are basically two life times of object C.
Object C is created along with A and B by a factory. For class1 I create the instance through master factory, but for second one I will have to pass the entire factory. The second class will now decide in run time (based on timer tick) how to create object C.
My question is regarding the second case: I am passing the entire factory, which besides the knowledge of creating object C also has a knowledge of creating A and B, is this considered bad design?
I am attaching a snapshot of what I am doing
Composition Snapshot
When working with multiple threads, each thread should get its own object graph. This means that every time you spin off some operation to a new thread (or a thread from the thread pool), you should ask the container again for the root object to work with. Prevent passing services from on thread to the other, because this scatters the knowledge about the thread-safety of your services throughout the code base, while with dependency injection you try to centralize this knowledge to a single place (the composition root). When this knowledge is scattered throughout the application, it becomes much harder to change the behavior of components what thread-safety is concerned.
When you do this, there is probably no need to even have two different configurations for that class. That class might simply be registeres as transient and because you resolve it at each pulse of the timer, each thread gets its own instance or the lifetime is scoped, in that case the class' lifetime will probably end when the timed operation ends.
The code that the timer calls and calls back into the container should be part of the composition root. Since the service is resolved on a background thread, you will often have to wrap that call in some sort of scope (lifetime scope, child container, etc). This allows that instance (or any other registered service) to live for the duration of that scope.

Can repository class be scoped as singleton in ASP.NET

I am trying to understand the scope of repository class in ASP.NET application. I assume they are thread safe in request scope since each request runs on a seperate thread. But how about having it singleton, is it a valid scenario.
Because these classes doesn't have state but only methods which manipulate data, so different threads executing these methods might be having different stack frames. Is my understanding right, could anyone provide more insights.
interface ICustomerRepository
{
List<Customers> GetAll();
Customer GetById(int id);
}
public class Customer : ICustomerRepository
{
//implement methods
}
Exposing a repository as a singleton for a concurrent environment is a bad idea.
You could possibly implement interface repository in a way that is safe to be used concurrently but this means that the only guarantee of concurrency consistency lies somewhere in the implementation. There is no other mechanism to enforce that concurrent calls would not fail, the contract at the programming language level (repository interface) is just too weak to express such requirement.
On the other hand, if each http context gets its own instance, the implementation details do not matter.
I suggest you read more on object lifetime. A singleton is just a specific example of a more general idea of controlling the lifetime. You can have objects with transient lifetime, objects that are shared in a single instance for the lifetime of you application but also objects that live in a context of a thread or an http context (that possibly spans multiple threads). And one of ways to control the lifetime is to have a factory that creates instances.
If you need something simple, you could have something that looks like a singleton but controls the lifetime in an arbitrary way:
http://netpl.blogspot.com/2010/12/container-based-pseudosingletons-in.html

How many instances of an Application object can run per application

I was reading the following post How to correctly use IHttpModule
*
Now lets think of the word itself. Application pool. Yes pool. It
means that a certain web application is running multiple
HttpApplication instances in one pool. Yes multiple. Otherwise it
wouldn't be called a pool. »How many?« you may ask. That doesn't
really matter as long as you know there could be more than one. We
trust IIS to do its job. And it obviously does it so well that it made
this fact completely transparent for us developers hence not many
completely understand its inner workings. We rely on its robustness to
provide the service. And it does. Each of these HttpApplication
instances in the pool keeps its own list of HTTP modules that it uses
with each request it processes.
*
I have a question that under what scenario multiple instances of an Application object can run for a single application. Till now I was aware of the fact that a single application object exists per application. So I am curious to know that is this true that multiple instances can run per application and how it is decided ?
Each HttpApplication object instance is unique to a single request. If your site is processing multiple requests in parallel, each one must have it's own instance of HttpApplication. That object has per-request state information that must not change during the request's lifetime (including the body of the request and response!)
The instances are pooled, as described in the article. Each one will be reused to service multiple subsequent requests, up to the limit set on the application pool, then it'll be allowed to die off.
Note that you're specifically asking about HttpApplication. This is distinct from the System.Windows.Forms.Application class, which is in fact a singleton class that only exists once per application.

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