Making any call to a function of an object thread safe
I was wondering how to modify old code to support threads /task .
So I was making a small project about making any function of an object thread safe.
NuGet Package at : https://www.nuget.org/packages/ThreadSafeObject/
The solution contain tests and 2 console project for .NET Core and .NET Framework 4.5.1
The usage is pretty easy
Let’s say you have this
Calculation c = new Calculation(); c.Add();
And you want
c.Add
to be thread safe
In the Package Manager Console write:
Install-Package ThreadSafeObject
Then modify your code to:
Calculation c = new Calculation(); dynamic ts = new ThreadSafe(c); ts.Add();
It is a toy project- however, it has tests to prove it is correct.
You can download the code source from https://github.com/ignatandrei/ThreadSafeObject/
I really don’t think this is such a great idea.
1. dynamic has significant overhead, and you lose IntelliSense.
2. This actually does NOT ensure thread safety of this method call. If Add happened to use some shared state (such as a static variable) then synchronizing around an instance of the object won’t be enough.
3. Method level locking is usually not enough. There’s a reason the concurrent collections use a special set of methods, such as GetOrAdd, rather than just implementing the existing collection interfaces.
1. Yes, dynamic have an overhead. However, this is an easy way to replace code .
2. For static variable – it is done . The lock is on a static object
3. You are right. However, this is an easy way to do it for existing code that you do not have access to the source code.
I agree with what you said, but I think there are solutions for some of the problems described. No solution I can think of for the first point, unless you use code generation. Frankly, that doesn’t sound so bad. Use some build step or manual tool to create a wrapper over objects, with the same signatures, but extra code on each. This also destroys the idea of the ThreadSafe library, but still 😀
The second can be solved easily by specifying the lock object. For example you take a collection and you wrap it up using the SyncRoot. The constructor of the ThreadSafe object could actually do this automatically for objects implementing ICollection. (hint, Andrei!)
As for the third, it cannot be solved by ThreadSafe because it is not a concurrent object access problem, but an attempt to execute multiple distinct operations atomically. It couldn’t be solved by any one object, since either operation could use any number of objects. So, while it is a problem, I don’t think it is one that ThreadSafe was even designed to solve.
I notice the code doesn’t support properties, only fields. I’ve added a pull request to fix that.
Thank you for the pull request. Do you think that I should release a new NuGet package?
There are several systems of “locking”:
– lock, which is syntactic sugar for the Monitor class (and in this case I would have preferred your code to use Monitor directly, for easier understanding of the functionality) and it only works in the AppDomain
– Mutex – which works per Operating System (and I agree above the scope of your project)
– Semaphore – advanced Mutex that allows you to specify many parameters to which Mutex remains closed
– SemaphoreSlim – advanced Monitor.
Since the most advanced and configurable method for the problem you want to solve is SemaphoreSlim, I would suggest using that and allowing the developer configurable methods of declaring the thread safety.
Code is on https://github.com/ignatandrei/ThreadSafeObject . Please modify at your will …. and make a pull/push request.