I've seen a lot of discussion about this subject on here.
If i have a static class w/ static methods that connects to a database or a server, is it a bad idea to use this in a multi-user environment (like a web page)? Would this make a new user's tread wait for previous users' threads to finish their calls before accepting a new one?
What would be the implications of this with multi-threading, also?
Thx!
If each static method is fully responsible for acquiring its resources and then disposing its resources within the scope of the method call (no shared state), then you shouldn't have any problem with threading that you wouldn't have using instance classes. I would suggest, however, that the bigger problem is that a reliance on public static methods (in static or non-static classes) creates many other design problems down the road.
First of all, you're binding very tightly to an implementation, which is always bad.
Second, testing all of the classes that depend on your static methods becomes very difficult to do, because you're locked to a single implementation.
Third, it does become very easy to create non-thread safe methods since static methods can only have static state (which is shared across all method calls).
Static methods do not have any special behaviour in respect to multithreading. That is, you can expect several "copies" of the method running at the same time. The same goes for static variables - different threads can access them all at once, there is no waiting there. And unless you're careful, this can create chaos.
Yes it's a bad idea.
When you use one connection for all your users if someone performs an action that requires, lets say 15 seconds, just for database access, all other users will have to wait in order to connect to the database
A little weirded out by this question. As to why you have so much static going on.
But I think you're asking about threading issues, so I would say go check out some of the docs on threading
http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx
Static is only defining the scope where the method is defined, and how it is bound / called. It has nothing to do with multi threading.
You need to be careful with static fields. They are shared by all threads. Threads are not waiting for each other, but you need locks to make it work.
But if your application is a bit more complex than Hello World, you should consider to have you methods not static but to use object oriented patterns.
If you do it right, it won't be a problem. If you do it wrong, it has the potential force sequential access to the resource.
Sometimes the difference between right and wrong can be very subtle and hard to spot, but the main thing is that no method should rely on or lock any "state" (members) of the class.
If you use one static connection to access the database, you will have to synchronize method calls. Multiple threads asking the database for data over a single connection will ... ehhmmm ... mess things up. So you are serializing all threads' data access and this will have a large impact on the performance.
If every call opens its own connection, you do not need to serialize all threads because there is no shared connection. Creating a connection per request is still an expensive design.
If you use a static connection pool you will reduce this performance impact because you only need to serialize the access to the connection pool.
Further, statics are in general not a good design decission - they make unit testing very complicated. You should consider using the Singleton or Monostate pattern.
I use static method for lookup objects. I can manage all lookups objects in one place (using caching) for the asp.net application and all methods call it by using static method.
By this way, I do not need to instantiate lookups objects everytime I need it and it reduce the need to call DB for performance enhancement.
Related
I have a background service IHostedService in dotnet core 3.1 that takes requests from 100s of clients(machines in a factory) using sockets (home rolled). My issue is that multiple calls can come in on different threads to the same method on a class which has access to an object (shared state). This is common in the codebase. The requests also have to be processed in the correct order.
The reason that this is not in a database is due to performance reasons (real time system). I know I can use a lock, but I don't want to have locks all over the code base.
What is a standard way to handle this situation. Do you use an in-memory database? In-memory cache? Or do I just have to add locks everywhere?
public class Machine
{
public MachineState {get; set;}
// Gets called by multiple threads from multiple clients
public bool CheckMachineStatus()
{
return MachineState.IsRunning;
}
// Gets called by multiple threads from multiple clients
public void SetMachineStatus()
{
MachineState = Stopped;
}
}
Update
Here's an example. I have a console app that talks to a machine via sockets, for weighing products. When the console app initializes it will load data into memory (information about the products being weighed). All of this is done on the main thread, to keep data integrity.
When a call comes in from the weigh-er on Thread 1, it will get switched to the main thread to access the product information, and to finish any other work like raising events for other parts of the system.
Currently this switching from Thread 1,2, ...N to the main thread is done by a home rolled solution, and was done to avoid having locking code all over the code base. This was written in .Net 1.1 and since moving to dotnet core 3.1. I thought there might be a framework, library, tool, technique etc that might handle this for us, or just a better way.
This is an existing system that I'm still learning. Hope this makes sense.
Using an in-memory database is an option, as long as you are willing to delegate all concurrency-inducing situations to the database, and do nothing using code. For example if you must update a value in the database depending on some condition, then the condition should be checked by the database, not by your own code.
Adding locks everywhere is also an option, that will almost certainly lead to unmaintanable code quite quickly. The code will probably be riddled with hidden bugs from the get-go, bugs that you will discover one by one over time, usually under the most unfortunate of circumstances.
You must realize that you are dealing with a difficult problem, with no magic solutions available. Managing shared state in a multithreaded application has always been a source of pain.
My suggestion is to encapsulate all this complexity inside thread-safe classes, that the rest of your application can safely invoke. How you make these classes thread-safe depends on the situation.
Using locks is the most flexible option, but not always the most efficient because it has the potential of creating contention.
Using thread-safe collections, like the ConcurrentDictionary for example, is less flexible because the thread-safety guarantees they offer are limited to the integrity of their internal state. If for example you must update one collection based on a condition obtained from another collection, then the whole operation can not be made atomic by just using thread-safety collections. On the other hand these collections offer better performance than the simple locks.
Using immutable collections, like the ImmutableQueue for example, is another interesting option. They are less efficient both memory and CPU wise than the concurrent collections (adding/removing is in many cases O(Log n) instead of O(1)), and not more flexible than them, but they are very efficient specifically at providing snapshots of actively processed data. For updating atomically an immutable collection, there is the handy ImmutableInterlocked.Update method available. It updates a reference of an immutable collection with an updated version of the same collection, without using locks. In case of contention with other threads it may invoke the supplied transformation multiple times, until it wins the race.
In my understanding, based on online information, ServicePartitionClient class is meant to be reused multiple times.
However I cannot find in the microsoft documentation if this class is thread-safe or not.
If not, I would like to know what is the common best practice to reuse such a class in a microservices environment: maybe lock() { ... } every time or create a new instance per call (not very useful in my case).
Thank you very much.
(at this moment in my code I'm using some static instances, and all appears to work correctly, but maybe it's going to fail under load later...)
EDIT:
I understand in some cases the class can be easily reused even if not thread safe (for example a background thread working on some queue can instantiate the class once and reuse it with no problem).
But in other common cases (such a microservice that receive a call and may need to call another microservice) reusing may become more complicated if the class is not thread safe.
It's in the nature of this class to perform I/O operation, so I think that a lock could be quite expensive due to race conditions.
Also in my understanding this class maintain in its state the last-resolved address for its target-service, and re-resolve it only in case of non-successful calls. Therefore instantiating a new class every time can be also expensive because I think in this case the newly instantiated ServicePartitionClient class will be forced to contact the naming-service every time to resolve the service address (two network roundtrips).
So I think Microsoft should really provide a thread-safe implentation for this class.
(sorry for my bad english)
From the web app, calls are made to a web service that in turn makes calls to a few static helper classes for filtering and sorting data - trying to think ahead if I will have unexpected behavior with multiple users
Make sure your static methods are thread-safe.
Thread safety fundamentally deals with ensuring that two threads don't access a shared resource in a conflicting manner.
There's a great overview on Wikipedia.
The best tutorial I have ever found about threading in the .NET environment is by Joe Albahari.
No, as long as those methods don't share access any shared resources. This could be:
A file on disk
Some static data
Another external resource
You just have to be sure that you aren't inadvertently sharing any resources / static data.
Using static methods is no issue. Just don't use static state unless you can synchronise access and keep performance
I came across a Data Access Layer Class that was made up entirely of static methods. This class was consumed by a Web Application
For e.g
public class DataAccessLayer
{
Public static PersonDetails GetDetails(int iPersonID);
{
//implementation
}
Public static bool SaveDetails(PersonDetails objPerson);
{
//implementation
}
}
Is it a good practice to write such code. I can understand the fact that the performance will be slightly better when I use static methods, but will this cause any concurrency errors when multiple users call the Page?
Is it a good practice to write such code.
Firing offense in my teams, breaks so many good practices I suggest whoever writes something like that goes to my competitors and works for them.
I can understand the fact that the performance will be slightly better when I use static methods.
Like 0.000000000000000000001%?
but will this cause any concurrency errors when multiple users call the Page?
Depends how the methods are written. It violates object orientation, though, makes dependency injection harder, makes it hard to use proper transactional demarcations under a transaction coordinator and makes it hard to unit test / mock things.
Static or not, you may get concurrency issues, it depends very much on how the actual code in your data access methods is written (e.g. use of transactions, are there fields used for concurrency checking in your data source etc.).
The static variable dies in a standalone application, because the
garbage collector cleans all your object because your application has
ended.
But if you are using this in a webapplication, your application is not
dead until your web server dies. So even if you closes the web browser,
your web server is not close. Try to shut down your server and your
variable will be no more.
I have a program that we'd like to multi-thread at a certain point. We're using CSLA for our business rules. At a one location of our program we are iterating over a BusinessList object and running some sanity checks against the data one row at a time. When we up the row count to about 10k rows it takes some time to run the process (about a minute). Naturally this sounds like a perfect place to use a bit of TPL and make this multi-threaded.
I've done a fair amount of multithreaded work through the years, so I understand the pitfalls of switching from single to multithreaded code. I was surprised to find that the code bombed within the CSLA routines themselves. It seems to be related to the code behind the CSLA PropertyInfo classes.
All of our business object properties are defined like this:
public static readonly PropertyInfo<string> MyTextProperty = RegisterProperty<string>(c => c.MyText);
public string MyText {
get { return GetProperty(MyTextProperty); }
set { SetProperty(MyTextProperty, value); }
}
Is there something I need to know about multithreading and CSLA? Are there any caveats that aren't found in any written documentation (I haven't found anything as of yet).
--EDIT---
BTW: the way I implemented my multithreading via throwing all the rows into a ConcurrentBag and then spawning 5 or so tasks that just grab objects from the bag till the bag is empty. So I don't think the problem is in my code.
As you've discovered, the CSLA.NET framework is not thread-safe.
To solve your particular problem, I would make use of the Wintellect Power Threading library; either the AsyncEnumerator/SyncGate combo or the ReaderWriterGate on its own.
The Power Threading library will allow you queue 'read' and 'write' requests to a shared resource (your CSLA.NET collection). At one moment in time, only a single 'write' request will be allowed access to the shared resource, all without thread-blocking the queued 'read' or 'write' requests. Its very clever and super handy for safely accessing shared resources from multiple threads. You can spin up as many threads as you wish and the Power Threading library will synchronise the access to your CSLA.NET collection.