prevent method from executing from different threads at the same time - c#

Am I correct that the only way to prevent a method from being executed twice at the same time is by using a lock statement?
private object lockMethod = new object();
public void Method() {
lock (lockMethod) {
// work
}
}
public void FromThread1() {
Method();
}
public void FromThread2() {
Method();
}
Of course I can also use MethodImpl(MethodImplOptions.Synchronized) what would be almost the same.
Are there other techniques?

Am I correct that the only method to prevent method to execute twice at the same time is using lock statement?
No, but this is the "standard" way, and probably the best. That being said, typically you'd use a lock to synchronize access to specific data, not to a method as a whole. Locking an entire method will likely cause more blocking than necessary.
As for other methods, the System.Threading namespace contains many other types used for synchronization in various forms, including ReaderWriterLockSlim, Semaphore, Mutex, the Monitor class (which is what lock uses internally), etc. All provide various ways to synchronize data, though each is geared for a different scenario. In this case, lock is the appropriate method to use.

Related

How to make static method thread safe?

I have written a static class which is a repository of some functions which I am calling from different class.
public static class CommonStructures
{
public struct SendMailParameters
{
public string To { get; set; }
public string From { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string Attachment { get; set; }
}
}
public static class CommonFunctions
{
private static readonly object LockObj = new object();
public static bool SendMail(SendMailParameters sendMailParam)
{
lock (LockObj)
{
try
{
//send mail
return true;
}
catch (Exception ex)
{
//some exception handling
return false;
}
}
}
private static readonly object LockObjCommonFunction2 = new object();
public static int CommonFunction2(int i)
{
lock (LockObjCommonFunction2)
{
int returnValue = 0;
try
{
//send operation
return returnValue;
}
catch (Exception ex)
{
//some exception handling
return returnValue;
}
}
}
}
Question 1: For my second method CommonFunction2, do I use a new static lock i.e. LockObjCommonFunction2 in this example or can I reuse the same lock object LockObj defined at the begining of the function.
Question 2: Is there anything which might lead to threading related issues or can I improve the code to be safe thread.
Quesiton 3: Can there be any issues in passing common class instead of struct.. in this example SendMailParameters( which i make use of wrapping up all parameters, instead of having multiple parameters to the SendMail function)?
Regards,
MH
Question 1: For my second method CommonFunction2, do I use a new
static lock i.e. LockObjCommonFunction2 in this example or can I reuse
the same lock object LockObj defined at the begining of the function.
If you want to synchronize these two methods, then you need to use the same lock for them. Example, if thread1 is accessing your Method1, and thread2 is accessing your Method2 and you want them to not concurrently access both insides, use the same lock. But, if you just want to restrict concurrent access to just either Method1 or 2, use different locks.
Question 2: Is there anything which might lead to threading related
issues or can I improve the code to be safe thread.
Always remember that shared resources (eg. static variables, files) are not thread-safe since they are easily accessed by all threads, thus you need to apply any kind of synchronization (via locks, signals, mutex, etc).
Quesiton 3: Can there be any issues in passing common class instead of
struct.. in this example SendMailParameters( which i make use of
wrapping up all parameters, instead of having multiple parameters to
the SendMail function)?
As long as you apply proper synchronizations, it would be thread-safe. For structs, look at this as a reference.
Bottomline is that you need to apply correct synchronizations for anything that in a shared memory. Also you should always take note of the scope the thread you are spawning and the state of the variables each method is using. Do they change the state or just depend on the internal state of the variable? Does the thread always create an object, although it's static/shared? If yes, then it should be thread-safe. Otherwise, if it just reuses that certain shared resource, then you should apply proper synchronization. And most of all, even without a shared resource, deadlocks could still happen, so remember the basic rules in C# to avoid deadlocks. P.S. thanks to Euphoric for sharing Eric Lippert's article.
But be careful with your synchronizations. As much as possible, limit their scopes to only where the shared resource is being modified. Because it could result to inconvenient bottlenecks to your application where performance will be greatly affected.
static readonly object _lock = new object();
static SomeClass sc = new SomeClass();
static void workerMethod()
{
//assuming this method is called by multiple threads
longProcessingMethod();
modifySharedResource(sc);
}
static void modifySharedResource(SomeClass sc)
{
//do something
lock (_lock)
{
//where sc is modified
}
}
static void longProcessingMethod()
{
//a long process
}
You can reuse the same lock object as many times as you like, but that means that none of the areas of code surrounded by that same lock can be accessed at the same time by various threads. So you need to plan accordingly, and carefully.
Sometimes it's better to use one lock object for multiple location, if there are multiple functions which edit the same array, for instance. Other times, more than one lock object is better, because even if one section of code is locked, the other can still run.
Multi-threaded coding is all about careful planning...
To be super duper safe, at the expense of potentially writing much slower code... you can add an accessor to your static class surround by a lock. That way you can make sure that none of the methods of that class will ever be called by two threads at the same time. It's pretty brute force, and definitely a 'no-no' for professionals. But if you're just getting familiar with how these things work, it's not a bad place to start learning.
1) As to first it depends on what you want to have:
As is (two separate lock objects) - no two threads will execute the same method at the same time but they can execute different methods at the same time.
If you change to have single lock object then no two threads will execute those sections under shared locking object.
2) In your snippet there is nothing that strikes me as wrong - but there is not much of code. If your repository calls methods from itself then you can have a problem and there is a world of issues that you can run into :)
3) As to structs I would not use them. Use classes it is better/easier that way there is another bag of issues related with structs you just don't need those problems.
The number of lock objects to use depends on what kind of data you're trying to protect. If you have several variables that are read/updated on multiple threads, you should use a separate lock object for each independent variable. So if you have 10 variables that form 6 independent variable groups (as far as how you intend to read / write them), you should use 6 lock objects for best performance. (An independent variable is one that's read / written on multiple threads without affecting the value of other variables. If 2 variables must be read together for a given action, they're dependent on each other so they'd have to be locked together. I hope this is not too confusing.)
Locked regions should be as short as possible for maximum performance - every time you lock a region of code, no other thread can enter that region until the lock is released. If you have a number of independent variables but use too few lock objects, your performance will suffer because your locked regions will grow longer.
Having more lock objects allows for higher parallelism since each thread can read / write a different independent variable - threads will only have to wait on each other if they try to read / write variables that are dependent on each other (and thus are locked through the same lock object).
In your code you must be careful with your SendMailParameters input parameter - if this is a reference type (class, not struct) you must make sure that its properties are locked or that it isn't accessed on multiple threads. If it's a reference type, it's just a pointer and without locking inside its property getters / setters, multiple threads may attempt to read / write some properties of the same instance. If this happens, your SendMail() function may end up using a corrupted instance. It's not enough to simply have a lock inside SendMail() - properties and methods of SendMailParameters must be protected as well.

Multiple locking task (threading)

I need to implement the class that should perform locking mechanism in our framework.
We have several threads and they are numbered 0,1,2,3.... We have a static class called ResourceHandler, that should lock these threads on given objects. The requirement is that n Lock() invokes should be realeased by m Release() invokes, where n = [0..] and m = [0..]. So no matter how many locks was performed on single object, only one Release() call is enough to unlock all. Even further if o object is not locked, Release() call should perform nothing. Also we need to know what objects are locked on what threads.
I have this implementation:
public class ResourceHandler
{
private readonly Dictionary<int, List<object>> _locks = new Dictionary<int, List<object>>();
public static ResourceHandler Instance {/* Singleton */}
public virtual void Lock(int threadNumber, object obj)
{
Monitor.Enter(obj);
if (!_locks.ContainsKey(threadNumber)) {_locks.Add(new List<object>());}
_locks[threadNumber].Add(obj);
}
public virtual void Release(int threadNumber, object obj)
{
// Check whether we have threadN in _lock and skip if not
var count = _locks[threadNumber].Count(x => x == obj);
_locks[threadNumber].RemoveAll(x => x == obj);
for (int i=0; i<count; i++)
{
Monitor.Exit(obj);
}
}
// .....
}
Actually what I am worried here about is thread-safety. I'm actually not sure, is it thread-safe or not, and it's a real pain to fix that. Am I doing the task correctly and how can I ensure that this is thread-safe?
Your Lock method locks on the target objects but the _locks dictionary can be accessed by any thread at any time. You may want to add a private lock object for accessing the dictionary (in both the Lock and Release methods).
Also keep in mind that by using such a ResourceHandler it is the responsibility of the rest of the code (the consuming threads) to release all used objects (a regular lock () block for instance covers that problem since whenever you leave the lock's scope, the object is released).
You also may want to use ReferenceEquals when counting the number of times an object is locked instead of ==.
You can ensure this class is thread safe by using a ConcurrentDictionary but, it won't help you with all the problems you will get from trying to develop your own locking mechanism.
There are a number locking mechansims that are already part of the .Net Framework, you should use those.
It sounds like you are going to need to use a combination of these, including Wait Handles to achieve what you want.
EDIT
After reading more carefully, I think you might need an EventWaitHandle
What you have got conceptually looks dangerous; this is bacause calls to Monitor.Enter and Monitor.Exit for them to work as a Lock statement, are reccomended to be encapsulated in a try/finally block, that is to ensure they are executed sequetally. Calling Monitor.Exit before Monitor.Enter will throw an exception.
To avoid these problems (if an exception is thrown, the lock for a given thread may-or-may-not be taken, and if a lock is taken it will not be released, resulting in a leaked lock. I would recomend using one of the options provided in the other answers above. However, if you do want to progress with this mechanism, CLR 4.0 added the following overload to the Monitor.Enter method
public static void Enter (object, ref bool lockTaken);
lockTaken is false if and only if the Enter method throws an exception and the lock was not taken. So, using your two methods using a global bool lockTaken you can create something like (here the example is for a single locker - you will need a Dictionary of List<bool> corresponding to your threads - or event better a Tuple). So in your method Lock you would have something like
bool lockTaken = false;
Monitor.Enter(locker, ref lockTaken);
in the other method Release
if (lockTaken)
Monitor.Exit(locker);
I hope this helps.
Edit: I don't think I fully appreciate your problem, but from what I can gather I would be using a Concurrent Collection. These are fully thead safe. Check out IProducerConsumerCollection<T> and ConcurrentBag<T>. These should facilitate what you want with all thread safter taken care of by the framework (note. a thread safe collection doesn't mean the code it executes is thread safe!). However, using a collection like this, is likely to be far slower than using locks.
IMO you need to use atomic set of functions to make it safe.
http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx
Mutexes I guess will help u.

Locking function body with function parameter object

Today I came across this piece of code
internal object UpdatePracownik(object employee)
{
lock (employee)
{
// rest of the code
}
return employee;
}
I was wondering if this is valid solution for locking access to function?
Wouldn't be better to use attribute
[MethodImpl(MethodImplOptions.Synchronized)]
instead of this kind of lock ?
Well it depends. If all threads call this method by passing the same globally visible object as parameter then they will all see the same lock and there will be no problems.
If instead each thread will call this method by passing its own object then locking is useless because they all see different locks. We must know the context in which the method is called to see if this is safe or not.
Using the synchronization method proposed by you makes the entire method body be wrapped in a lock(this) statement like:
internal object UpdatePracownik(object employee)
{
lock (this)
{
// code
}
}
which will guarantee atomicity of execution by multiple threads but may be too coarse-grain for your purposes and is generally not advisable.
Using the MethodImpl attribute to synchronise the method is equivalent to locking on an object that is specific to the method.
This means that only one thread at a time can run the method, but there might not be a need to exclude other threads as long as they don't use the same data.
It also means that the method is synchronised by itself, but you might want to lock other methods too using the same identifier. You might for example want the method DeletePracownik to be synchronised along with UpdatePracownik, so that you can't delete one object while it's being updated.
Locking on the employee instance is a bad idea, as is lock on 'this' both for the same reason: code outside of your control may also lock on those instances and cause deadlocks (blogs.msdn.com/b/bclteam/archive/2004/01/20/60719.aspx). It is preferable to use a private member:
private readonly object _lock = new object();
...
lock (_lock)
{
..
}
Furthermore you should familiarise yourself with ReaderWriterLockSlim. Often you may want to allow concurrent access to certain functions, unless a write operation is in progress:
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
public void ReadOp()
{
_rwLock.EnterReadLock(); //only blocks if write lock held
try
{
//do read op
}
finally
{
_rwLock.ExitReadLock();
}
}
public void WriteOp()
{
_rwLock.EnterWriteLock(); //blocks until no read or write locks held
try
{
//do write op
}
finally
{
_rwLock.ExitWriteLock();
}
}

Synchronization primitive "lock once"

I need a synchronization primitive which is similar to Monitor but doesn't require to Exit it as many times as I have enter it. If I enter Monitor by one thread and then reenter it by the same thread I will need to call Monitor.Exit twice. But I need to exit it by one call.
Now I use a some kind of Monitor wrapper which doesn't enter Monitor if it was already entered by current thread (and that's why then I can exit it by one call). But may be .NET Framework contains one?
I'm curious to know why you would ever call Monitor.Enter multiple times without an equal number of calls to Monitor.Exit. Typically any such synchronization code would look like this:
try
{
Monitor.Enter(lockObject);
// some code that needs to be synchronized
}
finally
{
Monitor.Exit(lockObject);
}
Assuming you are using try/finally wherever you acquire a lock using Monitor.Enter (which you should be), I'm having trouble seeing why you would need this "lock-once" class you're asking about.
In fact, you should basically never have to do this yourself anyway, as a much simpler approach that does essentially the same thing is to use a lock statement:
lock (lockObject)
{
// some code that needs to be synchronized
}
That said, I could certainly just be missing something.
how do you know it's the same thread and how to you ensure that when this threads leaves it is going to call exit before it leaves?
From the looks of it, you just need something else (in an outer level) that has the lock. Maybe an "entry point" method that locks and calls another method that has the meat of the work then you can call this other method many times without going past the lock.
public static void MethodOne()
{
lock (lockObj)
{
MethodTwo();
}
}
private static void MethodTwo()
{
//This method can be called multiple times
//without going past MethodOne and so you only
//lock once
}
private static void MethodThree()
{
}

Forcing threads in a service to wait for another thread to finish

I'm writing a service that has five different methods that can take between 5 seconds and 5 minutes to run.
The service will schedule these different methods to run at different intervals.
I don't want any of the methods to run concurrently, so how do I have the methods check to see if another method is running and queue itself to run when it finishes?
Anthony
If you want simple, and all the methods are in the same class, ou can just use [MethodImpl]:
[MethodImpl(MethodImplOptions.Synchronized)]
public void Foo() {...}
[MethodImpl(MethodImplOptions.Synchronized)]
public void Bar() {...}
For instance methods, this locks on this; for static methods, this locks on typeof(TheClass).
As such, these lock objects are public - so there is a remote (but genuine) chance that another bit of code might be locking on them. It is generally considered better practice to create your own lock object:
private readonly object syncLock = new object(); // or static if needed
...
public void Foo() {
lock(syncLock) {
...
}
}
etc
Aside: a curious fact; the ECMA spec doesn't define a specific pattern for [MethodImpl], even including an example of a private lock, as "valid". The MS spec, however, insists on this/typeof.
There's the MethodImplOptions.Synchronized attribute, as noted in the
article Synchronized method access in C#, but that can lead to deadlocks as noted at MSDN. It sounds like, for your usage, this won't be a big concern.
Otherwise, the simplest approach would be to use the lock statement to make sure that only one method is executing at a time:
class ServiceClass
{
private object thisLock = new object();
public Method1()
{
lock ( thisLock )
{
...
}
}
public Method2()
{
lock ( thisLock )
{
...
}
}
...
}
If you are using java, you can make the methods synchronized, which will prevent more than one thread from accessing it simultaneously.
In general, I strongly discourage using the MethodImpl(MethodImplOptions.Synchronized) attribute to do thread synchronization. If you are going to do multi-threaded programming you really should think very carefully about exactly where and how you should be locking.
I may be exaggerating a bit but I find too many similarities between the MethodImpl synchronization method and others such as the use of the End statement in VB. It often signals to me that you don't really know what you are doing and hope that this statement/method/attribute will magically solve your problem.

Categories

Resources