C# working with singleton from two different threads - c#

I am using the singleton pattern in a wpf app, but having doubts about how to make it work with multiple threads.
I have a class called Monitor which maintains a list of "settings" to watch, for different "devices". Outline shown below.
On my main thread I am doing
Monitor.getMonitor.register(watchlist) or Monitor.getMonitor.unregister(...) depending on the user input and I have a DispatchTimer running every 200ms that does a
Monitor.getMonitor.update()
public class Monitor
{
private Hashtable Master; //key=device, value=list of settings to watch
private static Monitor instance = new Monitor();
private Monitor() {}
public static Monitor getMonitor()
{
return instance;
}
public void register(watchlist){...}
public void unregister(...){...}
public void update(){...}
}
register()/unregister() perform add/remove to the hastable.
update() is only reading stuff out of the hashtable.
Depending on the number of devices and settings, update() is going to be iterating over the hastable and it contents, getting the latest values.
The main thread maybe calling register and unregister quite often and I want the gui to stay responsive. Whats a good way to do this?
Do I lock the hashtable, around add/remove and iterate, OR just surrond the iteration part in update with a try catch (ala gracefully fail) to catch any weird state the hashtable might get into(no locking) or is there some better way to do this (if update fails no prob..its going to be running in 200ms again anyway).
Not very sure about what is going on, cause the code as is hasnt really shown any problems which itself is making me a bit uneasy cause it just seems wrong. Thanks for any suggestions...

See my article on singleton implementations to make the singleton fetching itself threadsafe.
Yes, you'll need to lock when you modify or iterate over the hashtable. You could use a ReaderWriterLock (or preferrably ReaderWriterLockSlim in .NET 3.5) to allow multiple readers at a time. If you need to do a lot of work while you're iterating, you could always lock, take a copy, unlock, and then work on the copy - so long as the work doesn't mind the copy being slightly stale.
(If you're using .NET 2.0+, I'd suggest using the generic collections such as Dictionary<TKey, TValue> instead of Hashtable. I'd also suggest you rename your methods in line with .NET conventions. That code's got a distinct Java accent at the moment ;)

Yes, you should lock each operation:
public class Monitor
{
private Hashtable Master; //key=device, value=list of settings to watch
...
private object tableLock = new object();
public void register(watchlist)
{
lock(tableLock) {
// do stuff
}
}
}
You shouldn't consider using a try/catch block - exceptions shouldn't be considered as a "normal" situation, and you might end up with a corrupted object state without any exception.

How many rows are there? Unless the update() loop takes a long time to do the iterations, I'd probably lock. If the main thread is potentially doing a lot of register/unregister calls, then update might fail repeatedly -- if it fails for 20 or 30 consecutive calls, is that a problem?
That code looks ok to me. I'd probably make the class sealed. I'd also use a typed dictionary vs. a Hashtable.

Related

Multi-threading list pattern advice

I have made an application which also contains a folder/file scanner. I'm coming across a problem with the threading structure.
How it works:
For each folder/file it finds it starts a thread. There is a function inside each thread that uses a list to check if a similar item has been found so that it can add to the existing item. If it's not found it will add the item to the earlier mentioned list. The threads are executed parallel (async).
Problem:
Because it's async it will sometimes fail on the listcheck. This is caused because there is a time period between the check and adding to the list. Something that can happen is that the check returns that there is not a similar item, while there certainly is. This will result in the same item occurring in the list.
I have also made it that threads wait on each other. I really like the effect this gives it on the frontend. (items nicely adding to the list real time). But this takes way to long for a lot of folders/files.
Now I'm thinking of making a mix between the functions, but i would really like to see a combination of the speed of async threads and the safety of waiting on each thread.
Anybody any idea?
You should lock the entire code part that checks the list and adds a value.
Something like this:
private void YourThreadMethod(object state)
{
// long taking operation
lock (dictionary)
{
if (!dictionary.ContainsKey(yourItemKey))
{
// construct object, long taking operation
dictionary.Add(yourItemKey, createdObject);
}
}
}
In this way, every thread will have to wait until the list is free to use. If you want a more advanced solution, you could read into the ReaderWriterLockSlim class which gives a more fine grained solution.
The most sleekest approach is the usage of a ConcurrentDictionary<string, byte> when yourItemKey is type of string (otherwise adapt TKey and use a proper IEqualityComparer or implement IEquatable):
private readonly ConcurrentDictionary<string, byte> _list = new ConcurrentDictionary<string, byte>();
private void Foo(object state)
{
// looong operation
this._list.TryAdd(yourItemKey, 0);
}
public void Bar()
{
// this is how to query the content
this._list.Keys...;
}
The trick behind that is to not use a too complex object as the key, which may need disposal or has external references (I'd prefer any string representation), and a small type for the value, which just acts as a marker.
I would consider using one of the thread safe collections in C#. For your case something like a ConcurrentBag will be more efficient than using a lock.
In case there is a time delay between checking and adding, you can use ConcurrentDictionary. It has a TryAdd method which will return false if an item with the same key is already in the dictionary.

Cross-Thread access of a field in C#

If a class has an array, it doesn't really matter what of. Now one thread is adding data to said array, while another thread needs to process the data that is already in it. With my limited knowledge of multithreading, how could this work? The first problem I can think of is if an item is added while the other thread is processing what's still there. At first I thought that wouldn't be a problem, the processor thread would get it next time it processed, but then I realized that while the processor thread removes items it's already processed, the adding thread would not receive this change, possibly (?) wreaking havoc. Is there any good way to implement this behavior?
What you've described is basically the Reader Writers Problem. If you want to take care of multithreading, you're either going to need a concurrent collection, or use of a lock. The simplest implementation of a lock would just be locking an object
private Object myLock = new Object();
public MyClass ReadFromSharedArray()
{
lock(myLock)
{
//do whatever here
}
}
public void WriteToSharedArray(MyClass data)
{
lock(myLock)
{
//Do whatever here
}
}
There are better locks such as ReadWriterSlim locks but this sort of basic implementation should be a good starting point.
Also you mentioned adding/removing from arrays, I'm assuming you meant Lists (or better yet a Queue) - there's a ConcurrentQueuewhich could be a good replacement.

static class and multiple simultaneous requests

Suppose I have a static helper class that I'm using a lot in a web app. Suppose that the app receives about 20 requests per second for a sustained period of time and that, by magic, two requests ask the static class to do some work at the exact same nanosecond.
What happens when this happens?
To provide some context, the class is a used to perform a linq-to-sql query: it receives a few parameters, including the UserID, and returns a list of custom objects.
thanks.
It entirely depends on what your "some work" means. If it doesn't involve any shared state, it's absolutely fine. If it requires access to shared state, you'll need work out how to handle that in a thread-safe way.
A general rule of thumb is that a class's public API should be thread-safe for static methods, but doesn't have to be thread-safe for instance methods - typically any one instance is only used within a single thread. Of course it depends on what your class is doing, and what you mean by thread-safe.
What happens when this happens?
If your methods are reentrant then they are thread safe and what will happen is that chances are they will work. If those static methods rely on some shared state and you haven't synchronized access to this state chances are this shared state will get corrupted. But you don't need to hit the method at the same nanosecond by 20 requests to corrupt your shared state. 2 suffice largely if you don't synchronize it.
So static methods by themselves are not evil (well actually they are as they are not unit test friendly but that's another topic), it's the way they are implemented that matters in a multithreaded environment. So you should make them thread safe.
UPDATE:
Because in the comments section you mentioned LINQ-TO-SQL as long as all variables used in the static method are local, this method is thread-safe. For example:
public static SomeEntity GetEntity(int id)
{
using (var db = new SomeDbContext())
{
return db.SomeEntities.FirstOrDefault(x => x.Id == id);
}
}
you must ensure your methods are thread safe, so don't use static attributes to store any kind of state. If you are declaring new objects inside the static method, there is no problem because each thread have its own object.
It depends if the static class has any state or not (i.e. static variables shared across all calls). If it does not, then it's fine. If it does, it's not good. Examples:
// Fine
static class Whatever
{
public string DoSomething() {
return "something";
}
}
// Death from above
static class WhateverUnsafe
{
static int count = 0;
public int Count() {
return ++count;
}
}
You can make the second work fine using locks, but then you introduce deadlocks and concurrency issues.
I have built massive web applications with static classes but they never have any shared state.
It crashes out in a nasty way (if you are doing this to share state), avoid doing this in a webapp... Or alternativly protect the reads/writes with a lock:
http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx
But honestly you really should avoid using statics, unless you REALLY have to, and if you really have to you have to be very careful with your locking strategy and test it to destruction to make sure have managed to isolated reads and writes from each other

Making a program with singletons multithreaded C#

I have written a program in C#. Now I finished all the functionality and it works. But only running with one thread. I'm doing a lot of calculation and sometimes loading about 300 MB or more of measurement files into the application.
I now want to make the program multithreaded because the user experiance is really bad in times of intense processing or i/o operations.
What is the best way to refactor the program, so that it can be made multithreaded without too much affort? I know this is stuff I should have thougth before. But I havn't.
I used the singleton pattern for about 3 big and important modules which are involved in nearly every other functionality of the program.
I used a more or less clean MVC (Model View Control) architecture. So I wonder if it is maybe possible to let the User Interface run in one thread and the rest of the application in another.
If not, loading and parsing 300MB, creating objects will take about 3 minutes to finish. In this time the user gets no response from the GUI. :/
UPDATE:
My singletons are used as a kind of storage. One singleton saves the objects of the parsed measurement files, while the other singleton saves the result. I have different calculations, which use the same measurementfiles and creating results which they want to save using the other singleton. This is one problem.
The second is to keep the guy responsive to user action or at least avoid this warning that the window is not responding.
Thank you all for all advices. I will try them. Sorry for the late answere.
Generally, I avoid the singleton pattern because it creates a lot of issues down the road, particularly in testing. However, there is a fairly simple solution to making this work for multiple threads, if what you want is a singleton per thread. Put your singleton reference in a field (not a property) and decorate it with the ThreadStaticAttribute:
public class MySingleton
{
[ThreadStatic]
private static MySingletonClass _instance = new MySingletonClass();
public static MySingletonClass Instance { get { return _instance; } }
}
Now each thread will have its own instance of MySingleton.
The easiest way is to move all calculations to one separate thread and update the GUI using Invoke/InvokeRequired.
public partial class MyForm : Form
{
Thread _workerThread;
public MyForm()
{
_workerThread = new Thread(Calculate);
}
public void StartCalc()
{
_workerThread.Start();
}
public void Calculate()
{
//call singleton here
}
// true if user are allowed to change calc settings
public bool CanUpdateSettings
{
get { return !_workerThread.IsAlive; } }
}
}
In this way you have get a response GUI while the calculations are running.
The application will be thread safe as long as you don't allow the user to make changes during a running calculation.
Using several threads for doing the calculations is a much more complex story which we need more information for to give you a proper answer.
You can use TPL
You can make the loops with TPL parallel, and further more it is built-in with .NET 4.0 so that you don't have to change your program so much

What is a best approach to make a function or set of statements thread safe in C#?

What is a best approach to make a function or set of statements thread safe in C#?
Don't use shared read/write state when possible. Go with immutable types.
Take a look at the C# lock statement. Read Jon Skeet's article on multi threading in .net.
It depends on what you're trying to accomplish.
If you want to make sure that in any given time only one thread would run a specific code use lock or Monitor:
public void Func(...)
{
lock(syncObject)
{
// only one thread can enter this code
}
}
On the other hand you want multiple threads to run the same code but do not want them to cause race conditions by changing the same point in memory don't write to static/shared objects which can be reached by multiple at the same time.
BTW - If you want to create a static object that would be shared only within a single thread use the ThreadStatic attribute (http://msdn.microsoft.com/en-us/library/system.threadstaticattribute(VS.71).aspx).
Use lock statement around shared state variables. Once you ensured thread safety, run code through code profiler to find bottlenecks and optimize those places with more advanced multi-threading constructs.
The best approach will vary depending on your exact problem at hand.
The simplest approach in C# is to "lock" resources shared by multiple threads using a lock statement. This creates a block of code which can only be accessed by one thread at a time: the one which has obtained the "lock" object. For example, this property is thread safe using the lock syntax:
public class MyClass
{
private int _myValue;
public int MyProperty
{
get
{
lock(this)
{
return _myValue;
}
}
set
{
lock(this)
{
_myValue = value;
}
}
}
}
A thread aquires the lock at the start of the block and only releases the lock at the end of the block. If the lock is not available, the thread will wait until the lock is available. Obviously, access to the private variable within the class is not thread-safe, so all threads must access the value through the property to be safe.
This is by far the simplest way for threads to have safe access to shared data, however it only touches the tip of the iceberg of techniques for threading.
Write the function in such a way that:
It does not modify its parameters in any way
It does not access any state outside of its local variables.
Otherwise, race conditions MAY occur. The code must be thoroughly examined for such conditions and appropriate thread synchronization must be implemented (locks, etc...). Writing code that does not require synchronization is the best way to make it thread-safe. Of course, this is often not possible - but should be the first option considered in most situations.
There's a lot to understand when learning what "thread safe" means and all the issues that are introduced (synchronization, etc).
I'd recommend reading through this page in order to get a better feel for what you're asking: Threading in C#. It gives a pretty comprehensive overview of the subject, which sounds like it could be pretty helpful.
And Mehrdad's absolutely right -- go with immutable types if you can help it.

Categories

Resources