can lock work across multiple objects in c#? - c#

I have been looking for a way to lock a particular piece of code.
namespace x
{
public class y
{
private Object obj = new Object();
private void A()
{
lock(obj)
{
//critical section
}
}
}
}
Upon request my application enters method A from different sources(which uses class Y) and it is seen that lock object is failing to protect the critical section.
I am looking for the way to protect critical section even though multiple objects try to access the piece of code and i do not want to use static lock object.
Please help me.

Lock do the job, but you lock an instance field, it will protect your critical section only for same instance. If you want to lock for all instance, make your flag (Obj) static.
namespace x
{
public class y
{
static private Object obj = new Object();
private void A()
{
lock(obj)
{
//critical section
}
}
}
}

Related

How to run the code only once in multithreading environment? [duplicate]

The following code block, performs loading of an object in C#.
public bool IsModelLoaded { get; set; }
public override MyObject Load()
{
if (!IsModelLoaded)
{
Model = MyService.LoadMyObject(Model);
IsModelLoaded = true;
}
return Model;
}
My intention is to run this block only once, and hence loading the Model only once. Nevertheless, this code block runs twice from 2 different threads.
How can I make sure that this block runs only once? (on multiple threads).
Use the Lazy<T> Class:
private readonly Lazy<MyObject> myObject;
public MyClass()
{
myObject = new Lazy<MyObject>(() =>
{
return MyService.LoadMyObject();
}, LazyThreadSafetyMode.ExecutionAndPublication);
}
public bool IsModelLoaded
{
get { return myObject.IsValueCreated; }
}
public override MyObject Load()
{
return myObject.Value;
}
Simplest would be to add
[MethodImpl(MethodImplOptions.Synchronized)]
public override MyObject Load()
{
//snip
}
but be aware this puts a lock on the entire object, not just the method. Not really great practice.
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions.aspx
Synchronized
Specifies that the method can be executed by only one thread at a time. Static methods lock on the type, whereas instance methods lock on the instance. Only one thread can execute in any of the instance functions, and only one thread can execute in any of a class's static functions.
I are trying to implement singleton pattern. But your version is not thread safe. Read more here: http://www.dofactory.com/Patterns/PatternSingleton.aspx. Try to use this implementation:
public sealed class Singleton
{
static Singleton instance=null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
If you want to write thread safe code and make sure that the block runs only once, you can write like this:
private System.Object lockThis = new System.Object();
public override MyObject Load()
{
lock (lockThis) {
if (!IsModelLoaded)
{
Model = MyService.LoadMyObject(Model);
IsModelLoaded = true;
}
}
return Model;
}
Action myCodeBlock = ()=>
{
//do your job
//...
myCodeBlock = ()=>{};
}
After calling myCodeBlock() once it will be rewritten by method that does nothing. You still need to make sure this metod is called safely - use lock or whatever.
You can use lock Statement (C# Reference)
Create a static object (like a boolean) that determines if the code has ran or not by putting it in an if statement :)
EDIT: I'm not sure if this is threadsafe, so it might not be the solution for you.

Thread safe coding by using lock statement

I am having some doubts while using lock statement to make thread safe, here is my code:
public class Class1
{
public ClassName _Obj;
private static object LockObj = new object();
public ClassName Obj
{
get { return _Obj ?? (_Obj = new ClassName()); }
}
public void ThreadA()
{
//lock (LockObj) --able to handle the thread
//lock (Obj) --it is also able to handle the thread
lock (this) // --same for this also
{
for (int i = 0; i < 1000; i++)
{
Obj.ValueA = i;
// Processing on Obj..
}
}
}
}
public class ClassName
{
public int ValueA { get; set; }
}
In this block of code ThreadA can be made safe by using a lock statement. But which is the exact way of passing an argument to the lock statement? The same result can be achieved by passing ClassName object i.e Obj, LockObj object which is static or by this object also. Please make it clear, which is better and why?
From MSDN to explain lock statement:
In general, avoid locking on a public type, or instances beyond your
code's control. The common constructs lock (this), lock (typeof
(MyType)), and lock ("myLock") violate this guideline:
lock (this) is a problem if the instance can be accessed publicly.
lock (typeof (MyType)) is a problem if MyType is publicly accessible.
lock("myLock") is a problem because any other code in the process using the same string, will share the same lock.
Best practice is to define a private object to lock on, or a private
static object variable to protect data common to all instances.

All threads only in one method at a time?

I have several objects inheriting from ClassA, which has an abstract method MethodA.
Each of these inheriting objects can allow up to a specific number of threads simutaneously into their MethodA.
The catch: Threads can only be in an object's MethodA, while no other objects' MethodA is being processed at the same time.
How can I solve this? I am thinking about using a semaphore, but don't know exactly how to do it, because I just can't wrap my head around the problem enough to get a solution.
EDIT:
Example code (may contain syntax errors:)
public class ClassA
{
public virtual void MethodA{}
}
public class OneOfMySubclassesOfClassA // there can be multiple instances of each subclass!
{
public override void MethodA{
// WHILE any number of threads are in here, THIS MethodA shall be the ONLY MethodA in the entire program to contain threads
EDIT2: // I mean: ...ONLY MethodA of a subclass (not of a instance of a subclass) in the entire program...
}
}
...and more subclasses...
The derived type is used as type argument in the base class together with a static semaphore to get one semaphore shared between all instances of each subclass. And then there is some mess to ensure that only one type is active. A quick test indicates that this works correctly but there is an issue.
Assume for example that the method of ClassA1 is currently executing. If new request to execute this methods arrive with high frequency it may happen that other derived classes get no chance to execute because there are constantly new threads executing the method of class ClassA1.
internal abstract class ClassA<TDerived> : ClassA
{
private const Int32 MaximumNumberConcurrentThreads = 3;
private static readonly Semaphore semaphore = new Semaphore(ClassA<TDerived>.MaximumNumberConcurrentThreads, ClassA<TDerived>.MaximumNumberConcurrentThreads);
internal void MethodA()
{
lock (ClassA.setCurrentlyExcutingTypeLock)
{
while (!((ClassA.currentlyExcutingType == null) || (ClassA.currentlyExcutingType == typeof(TDerived))))
{
Monitor.Wait(ClassA.setCurrentlyExcutingTypeLock);
}
if (ClassA.currentlyExcutingType == null)
{
ClassA.currentlyExcutingType = typeof(TDerived);
}
ClassA.numberCurrentlyPossiblyExecutingThreads++;
Monitor.PulseAll(ClassA.setCurrentlyExcutingTypeLock);
}
try
{
ClassA<TDerived>.semaphore.WaitOne();
this.MethodACore();
}
finally
{
ClassA<TDerived>.semaphore.Release();
}
lock (ClassA.setCurrentlyExcutingTypeLock)
{
ClassA.numberCurrentlyPossiblyExecutingThreads--;
if (ClassA.numberCurrentlyPossiblyExecutingThreads == 0)
{
ClassA.currentlyExcutingType = null;
Monitor.Pulse(ClassA.setCurrentlyExcutingTypeLock);
}
}
}
protected abstract void MethodACore();
}
Note that a wrapper method is used to call the actual implementation in MethodACore. All the synchronization objects shared between all derived classes are in a non-generic base class.
internal abstract class ClassA
{
protected static Type currentlyExcutingType = null;
protected static readonly Object setCurrentlyExcutingTypeLock = new Object();
protected static Int32 numberCurrentlyPossiblyExecutingThreads = 0;
}
The derived classes will look like this.
internal sealed class ClassA1 : ClassA<ClassA1>
{
protected override void MethodACore()
{
// Do work here.
}
}
internal sealed class ClassA2 : ClassA<ClassA2>
{
protected override void MethodACore()
{
// Do work here.
}
}
Unfortunately I have no time to explain how and why this works in more detail right now but I will update the answer tomorrow.
public abstract class Foo
{
private static Type lockedType = null;
private static object key = new object();
private static ManualResetEvent signal = new ManualResetEvent(false);
private static int threadsInMethodA = 0;
private static Semaphore semaphore = new Semaphore(5, 5);//TODO set appropriate number of instances
public void MethodA()
{
lock (key)
{
while (lockedType != this.GetType())
{
if (lockedType == null)
{
lockedType = this.GetType();
//there may be other threads trying to get into the instance we just locked in
signal.Set();
}
else if (lockedType != this.GetType())
{
signal.WaitOne();
}
}
Interlocked.Increment(ref threadsInMethodA);
}
semaphore.WaitOne();
try
{
MethodAImplementation();
}
finally
{
lock (key)
{
semaphore.Release();
int threads = Interlocked.Decrement(ref threadsInMethodA);
if (threads == 0)
{
lockedType = null;
signal.Reset();
}
}
}
}
protected abstract void MethodAImplementation();
}
So there are a few key points here. First off, we have a static object that represents the only instance that is allowed to have threads. null means the next thread to come along can put in "their" instance. If another instance is the "active" one the current thread waits on the manual reset event until either there is no locked instance, or the locked instance changed to what might possibly be that thread's instance.
It's also important to count the number of threads in the method to know when to set the locked instance to null (setting to to null without keeping track of that would let new instances start while a few of the previous instances were finishing.
Locks around another key at the start and end are rather important.
Also beware that with this setup it's possible for one type to starve out other types, so if this is a heavily contended resource it's something to watch out for.
Assuming you have a list of all relevant instances, this code will lock on all other instances and thus allow only one instance's code to be executed at any given time:
void MethodA()
{
foreach (var obj in objects)
if (obj != this)
Monitor.Enter(obj);
try
{
// do stuff
}
finally
{
foreach( var obj in objects)
if (obj != this)
Monitor.Exit(obj);
}
}

Lock code section to one entrance at a time

I am trying to restrict access to an singletone object so only one thread
use it at time, Furthermore, I want to prevent from the same thread accessing twice
to the restricted code.
I tried the Lock method and i found out that its dosn't lock the thread that locked her, but only other threads..
as below:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
public class SomeWorker
{
private readonly Timer _doWorkTimer = new Timer(20);
public SomeWorker()
{
InitiateTimer();
}
private void InitiateTimer()
{
_doWorkTimer .Elapsed += DoWorkElapse;
_doWorkTimer .Enabled = true;
}
private void DoWorkElapse(object source, ElapsedEventArgs e)
{
DoSomeWork();
}
private void DoSomeWork()
{
// I know that lock on string is wrong!
// Its just for the example only I
// Its just to make sure all the program is use the same lock..
lock ("ConnectionLock")
{
Console.WriteLine("Lock");
var inst = Singletone.Instance;
// Do Some Work on "inst" ...
Console.WriteLine("Unlock");
}
}
}
The result in the console for example is:
.
.
.
Lock
Unlock
Lock
Lock
Unlock
.
.
.
As we can see, 2 Lock comments shows one after another
So its mean that the "DoSomeWork()" accessed twice by the timer thread.
Anyone have any idea how to make this lock work?
Other Sync methods maby?
thanx.
You aren't doing your locking properly (and to top it off you are taking a lock on a string which is a big no-no). To save time, please read this article from Jon Skeet and implement one of the patterns to save yourself a headache.
In your code you have
public static Singletone Instance()
{
if (_instance == null)
{
lock (_instance)
{
if (_instance == null)
{
_instance = new Singletone ();
}
}
}
return _instance;;
}
Think about it. if (_instance == null) you do lock (_instance). So you lock using null. That's not good at all.
In MSDN lock Statement (C# Reference) the given example of how to use lock is:
class Account
{
decimal balance;
private Object thisLock = new Object();
public void Withdraw(decimal amount)
{
lock (thisLock)
{
if (amount > balance)
{
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
I guess you should follow it and have a separate object to use it as a lock.
And secondly, thread syncronization primitives are used to separate access to shared resources for different threads. If you need to separate access from one thread, you simply need to use flags. Something like this:
bool isBusy = false;
public static void Foo()
{
if (!isBusy)
{
isBusy = true;
try
{
//do the job
}
finally
{
isBusy = false;
}
}
}
Here you should understand that you simply skip the "locked-by-flag" code. On the contrary if you want to make the thread wait for itself, especially in a multithreading application, I guess it looks like it should be redesigned.
The easiest way to implement a singleton in .NET is:
public class Singleton : IDisposable
{
private readonly static Singleton _instance = new Singleton();
private readonly static object lockObject = new object();
static Singleton()
{
}
private Singleton()
{
InitiateConnection();
}
public static Singleton Instance
{
get { return _instance; }
}
/// <summary>
/// Method that accesses the DB.
/// </summary>
public void DoWork()
{
lock (lockObject)
{
//Do Db work here. Only one thread can execute these commands at a time.
}
}
~Singleton()
{
//Close the connection to DB.
//You don't want to make your singleton class implement IDisposable because
//you don't want to allow a call to Singleton.Instance.Dispose().
}
}
Read the excellent article on Singleton Pattern implementations in .NET that Bryan suggested in his answer. The above implementation is based on the fourth version described in the article. The CLR guarantees that the construction of the static field will thread-safe hence you do not need locking there. However you will need locking if your object has state (fields) that can be changed.
Note that there is a private readonly object used for ensuring mutual exclusion on the DoWork method. This way a single thread can call DoWork at a time. Also note that there is no way that the same thread can call this method twice at the same time since a thread executes instructions sequentially. The only way this method could be called twice from a single thread is if inside DoWork you call another method that eventually calls DoWork. I can't see the point of doing this and if you do then take care to avoid stack overflows. You could follow the suggestion of Konstantin and use a flag but IMHO you should redesign DoWork to do just one thing and avoid scenarios like these.

What to pass to the lock keyword?

What is the difference (if any) between using
void MethodName()
{
lock(this)
{
// (...)
}
}
or
private object o = new object();
void MethodName()
{
lock(o)
{
// (...)
}
}
?
Is there a difference in performance? Style? Behaviour?
lock(this) will lock on the "current" object.
Locking on "this" is usually a bad idea as it exposes the lock to other code; I prefer to have a readonly field, like this:
public class Foo
{
private readonly object padlock = new object();
public void SomeMethod()
{
lock(padlock)
{
...
}
}
}
That way all calls to SomeMethod (and anything else in Foo which locks on padlock) will lock on the same monitor for the same instance of Foo, but nothing else can interfere by locking on that monitor.
In reality, unless you're dealing with "rogue" code, it's unlikely that other code will actually lock on the reference to an instance of Foo, but it's a matter of encapsulation.
The difference is that anyone can lock on your instance, but only you can lock on a private object.
This helps prevent deadlocks.
For example:
Let's say that Microsoft used lock(this) in the Control class.
Then, if someone else locks on a Control instance, his lock would prevent the code in Control from running, which is not what he wants.
This is particularly bad if you lock on types that are shared across AppDomains
The pattern I usually follow is this, for a class declared static....
public static class SomeClass{
private static object objLock = new object();
....
public static object SomeProperty{
get{
lock(objLock){
// Do whatever needs to be done
}
}
set{
lock(objLock){
}
}
}
}
Likewise for a normal class I would follow this pattern:
public class SomeClass{
private readonly object objLock = new object();
....
public object SomeProperty{
get{
lock(objLock){
// Do whatever needs to be done
}
}
set{
lock(objLock){
}
}
}
}
In that way, no one can lock on my instance and will prevent deadlocks from occuring...
Edit: I have amended this article to make it clearer with regards to the code where the basis of the static lock would be used and for a normal class... Thanks Steven and Dalle for their point outs...
There is a difference in scope and there can be a difference in behavior
(incidentally, using "this" is not recommended by MS
// in this case, your lock object is public, so classes outside of this can lock on the same thing
lock(this) {}
// in this case, your lock is private, and only you can issue a lock statement against it
private object lockobj = new object()
..
lock(this.lockobj) {}
// this one is WRONG -- you willget a new object instance every time, so your lock will not provide mutual exclusion
void SomeMethod()
{
// using a local variable for a lock -- wrong
object obj = new object();
lock(obj) {}
}

Categories