Lock code section in c# - c#

My question may sound like many others here but it has a flavor I didn't find.
I am trying to understand the following logic
A generic object
public class GenericClass
{
public static void DoSomething(Object lockObj)
{
lock(lockObj)
{
// do something here
}
}
}
Class A
internal class A
{
private static _aLock = new Object();
public void Do_A_Thing()
{
GenericClass.DoSomething(_aLock);
}
}
Class B
internal class B
{
private static _bLock = new Object();
public void Do_B_Thing()
{
GenericClass.DoSomething(_bLock);
}
}
I just hope to confirm if my explanation is correct:
If multiple threads of class "A" will attempt simultaneously access code in "genericClass" method "DoSomething", this method will be locked to all but one instance of class "A". But a single instance of class "B" will be able to proceed with execution any time. If class "B" will also have multiple instances execute, they will not interfere with class "A" locks.
Is this correct based on what you see above?

Yes, your description sounds correct. It is perhaps a little unusual to pass the lock object in, but it'll work fine. The only change I would suggest is to make the static fields readonly so you can't accidentally change the value to a different object reference.

Your conclusion is correct but it is not a good practice to pass locked object around. I suggest to put the lock inside class A and B respectively.
I suggest to write:
internal class A
{
private static readonly _aLock = new Object();
public void Do_A_Thing()
{
lock (_aLock)
{
GenericClass.DoSomething();
}
}
}
Do you have a specific reason to put the lock in another class? Maybe you can solve your problem in a different way?
Also keep in mind that in some conditions, maybe it is not your case, you can have a deadlock if class A and B call each other (A->B->A).

Yes, that is correct. The locks in A and the locks in B are completely unaware of each other. The code will only be blocked when there is another thread locking it with the same object as identifier.

If you are using generics, then something like
public class MyGadget<T>
{
static readonly SyncRoot = new object() ;
public T SynchronizedMethod()
{
lock ( SyncRoot )
{
SynchronizedMethodGuts() ;
}
}
}
should do what you want because MyGadget<Foo> and MyGadget<Bar> are different classes: they each have their own, different SyncRoot field.

Related

Need to synchronize two classes

I have two classes A & B. Both are calling each other and having their own locks. I am getting a deadlock in one particular scenario. Here is the sample code.
class A : Interface1, Interface2
{
private B _bInstance = new B();
private object _aSync = new object();
private static A Instance;
private A(){}
public GetInstance()
{
if (Instance == null) Instance = new A();
return Instance;
}
void Method1()
{
lock(_aSync)
{
_bInstance.Method1();
}
}
void WriteData()
{
lock (_aSync)
{
WriteToFile();
}
}
}
class B
{
private object _bSync = new object();
void Method1()
{
lock (_bSync)
{
// Have some code here which need to protect my
// member variables.
A.GetInstance.WriteData();
}
}
void OneSecondTimerEvent()
{
lock (_bSync)
{
// Have some code here which need to protect my
// member variables.
A.GetInstance.WriteData();
}
}
}
How do I synchronize the OneSecondTimerEvent(), if One second timer gets triggered When the A.Method1() is being executed?
Yes, your code shows canonical example of deadlock - 2 resources waiting for each other to continue.
To resolve you can:
manually order lock statements (i.e. B never takes additional locks if A already have lock),
scope locks to only internal state of each class and never nest locks. In this case sometimes you'd need to copy state to call external methods.
use other synchronization primitives/constructs that allow such nesting (i.e. Reader-Writer locks).
Rather than try and solve this particular deadlock issue (which btw, is a classic result of locking things in an inconsistent order), I would strongly advise designing a better relationship between A and B. The fact you had to use a static instance to achieve a circular dependency should be a big clue you've done something wrong. Perhaps A and B should reference a 3rd class C, which is solely responsible for locking and writing the data? (Although it's difficult to say without a bit more context).

Are Static Fields thread Safe

We have a Static field in a abstract class
ABSTRACT CLASS :-
public abstract class BaseController
{
private static string a;
private static string b;
protected abstract SomeArray[] DoSomeThing();
}
And a derived class
public class Controller1:BaseController
{
protected override SomeArray[] DoSomthing()
{
//////
In this method we are setting the static variables with different values
}
}
We also have a class which is starting threads
public class SomeClass
{
public SomeClass()
{
\\ we are setting the controller we want to call, i mean to decide which base class to call
}
public void Run()
{
Thread t = new Thread(StartThread);
t.Start();
}
public void StartThread()
{
_controller.DoSomeThing();
}
}
All the above service is in a WCF service, and the same client tries to call multiple times which means we have multiple threads running at the same time, we have seen issues where the static variable which we are setting and using that for some DB update process is sometimes having wrong values
I have read some blogs which says static fields are not thread safe, Can some body please help me understand what could be going wrrong in our code and why we are having some incorrect values passed to the DB.
By definition, a static field or member is shared among all instances of that class, only one instance of that field or member exisits; thus, it is not thread safe.
You have two options, either to synchronize the access (basically, using Monitor class) to that field or to use the ThreadStaticAttribute on that field.
However, i advice to reorganize your class hierarchy so that each class has its own instance of the field or member.
Please note that if there are multiple threads working on the same instance of the class Controller, then we go back to the same problem and you should synchronize access to that instance field.
Good Luck

calling a static parameter from one public class to another

I'm trying to write a multi-threaded app , and I need to use Monitoer.Enter/Exit/Wait/Pulse
I've created a Lock object and used it in its own class like that
public partial class domain
/*I dont sure this is the good practice way to mange DDD Layers (if anybody have a comment about it)*/
{
Public class Peer2PeerCom
{
public static readonly object locker = new object();
//other stuff here
//...
//somwhere here
Monitor.Pulse(locker);
}
}
in the other class I want/need to use the locker like that
public class Control
{
public domain.Peer2PeerCom Dom_P2PCom = new domain.Peer2PeerCom();
internal void connection ( int port , string IpAdress)
{
Monitor.Enter(Dom_P2PCom.locker);
//do stuff here
Monitor.wait(Dom_P2PCom.locker);
//..
Monitor.Exit(Dom_P2PCom.locker);
}
}
But when I try I cannot recognize the locker , I think it is because it is static but I dont understand how to correct it without making the entire class static
You're trying to access a static member via a reference. That doesn't work in C#, fortunately - it can lead to very misleading code where it's allowed, e.g. in Java.
Instead, you should use the name of the class to access a static member:
lock (domain.Peer2PeerCom.locker)
{
...
// This should probably be in a while loop...
Monitor.Wait(domain.Peer2PeerCom.locker);
}
(I've used lock rather than explicitly calling Monitor.Enter and Monitor.Exit - it's more idiomatic, and easier to get right - in the code you've given, any exception in the code after entering the monitor would have cause the monitor to be "leaked" - you wouldn't have exited it.)
In general, I'd strongly recommend against using a public static field for a shared lock like this. It makes it much harder to reason about what's using the lock than if it's private within a class. (I'd recommend against public fields in general, along with underscores in class names, classes which are nested for no particular reason, and a class name of domain, too...)

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) {}
}

how to destroy a Static Class in C#

I am using .net 1.1. I have a session class in which I have stored many static variables that hold some data to be used by many classes.
I want to find a simple way of destroying this class instead of resetting every variable one by one. For example if there is a static class MyStatic, I would have liked to destroy/remove this class from the memory by writing MyStatic = null, which is not currently possible,
Additional question.
The idea of singleton is good, but I have the following questions:
If singleton is implemented, the 'single' object will still remain in the memory. In singleton, we are only checking if an instance is already existing. how can i make sure that this instance variable also gets destroyed.
I have a main class which initializes the variable in the static class. Even if I plan to implement a Rest() method, I need to call it from a method, for eg, the destructor in the main class. But this destructor gets called only when GC collects this main class object in the memory, which means the Reset() gets called very late
thanks
pradeep
Don't use a static class to store your variables. Use an instance (and make it a singleton if you only want one instance at any given time.) You can then implement IDisposible, and just call Dispose() when you want to destroy it.
For more information check out this site: http://csharpindepth.com/Articles/General/Singleton.aspx
EDIT
The object is still subject to garbage collection, so unless you are using lots of unmanaged resources, you should be fine. You can implement IDisposible to clean up any resources that need to be cleaned up as well.
Instead of a static class, have a static instance of a class:
class Foo
{
public int Something;
public static Foo Instance = new Foo();
public void Reset()
{
Instance = new Foo();
}
}
void test
{
int i = Foo.Instance.Something;
}
You can also delegate to an instance of the class:
class Foo
{
public int Something
{
get { return instance.something; }
}
private int something;
private static Foo instance = new Foo();
public void Reset()
{
instance = new Foo();
}
}
void test
{
int i = Foo.Something;
}
There's no way to destroy a static unless it resides in a separate AppDomain in which case you can get rid of it by unloading the AppDomain. However it is usually better to avoid statics.
EDIT: Additional question
When the singleton is no longer referenced it will be collected just as everything else. In other words, if you want it collected you must make sure that there are no references to it. It goes without saying that if you store a static reference to your singleton, you will have the same problem as before.
Use a Singleton like ktrauberman said, and have an initialization method or a reset method. You only have to write the code once and call the method.
You destroy objects, not classes. There's nothing wrong with static classes--C# provides them for a reason. Singletons are just extra overhead, unless you actually need an object, e.g. when you have to pass the object as a parameter.
Static classes contain only static variables. These variables tend to last for the lifetime of the app, in which case you don't have to worry about disposing referenced objects, unless you have a mild case of OCD. That just leaves the case where your static class allocates and releases resources throughout its lifetime. Dispose of these objects in due course as you usually would (e.g., "using...").
The best way in your condition is to have an Reset() method built-in as well, which can reset the values of the class.
class myclass
{
private static myclass singleobj = null;
private myclass(){}
public static myclass CreateInstance()
{
if(singleobj == null)
singleobj = new myclass();
return singleobj
}
}
Building on Ahemd Said's answer: (and props to him!)
class Singleton
{
private static Singleton instance = null;
private Singleton(){} // private constructor: stops others from using
public static Singleton Instance
{
get { return instance ?? (instance = new Singleton()); }
set {
if (null != value)
{ throw new InvalidValueException(); }
else
{ instance = null; }
}
}
}
void SampleUsage()
{
Singleton myObj = Singleton.Instance;
// use myObj for your work...
myObj.Instance = null; // The set-operator makes it ready for GC
}
(untested... but mostly right, I think)
You could also add in usage of the IDispose interface for more cleanup.
You can create a method in the static class which resets the values of all properties.
Consider you have a static class
public static class ClassA
{
public static int id=0;
public static string name="";
public static void ResetValues()
{
// Here you want to reset to the old initialized value
id=0;
name="";
}
}
Now you can use any of the below approaches from any other class to reset value of a static class
Approach 1 - Calling directly
ClassA.ResetValues();
Approach 2 - Invoking method dynamically from a known namespace and known class
Type t1 = Type.GetType("Namespace1.ClassA");
MethodInfo methodInfo1 = t1.GetMethod("ResetValues");
if (methodInfo1 != null)
{
object result = null;
result = methodInfo1.Invoke(null, null);
}
Approach 3 - Invoking method dynamically from an assembly/set of assemblies
foreach (var Ass in AppDomain.CurrentDomain.GetAssemblies())
{
// Use the above "If" condition if you want to filter from only one Dll
if (Ass.ManifestModule.FullyQualifiedName.EndsWith("YourDll.dll"))
{
List<Type> lstClasses = Ass.GetTypes().Where(t => t.IsClass && t.IsSealed && t.IsAbstract).ToList();
foreach (Type type in lstClasses)
{
MethodInfo methodInfo = type.GetMethod("ResetValues");
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(null, null);
}
}
break;
}
}
Inject the objects into the static class at startup from a non static class that implements IDisposable, then when your non static class is destroyed so are the objects the static class uses.
Make sure to implement something like "Disable()" so the static class is made aware it's objects have just been set to null.
Eg I have a logger class as follows:
public static class Logger
{
private static Action<string, Exception, bool> _logError;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError != null) _logError = logError;
}
public static void LogError(string msg, Exception e = null, bool sendEmailReport = false)
{
_logError?.Invoke(msg, e, sendEmailReport);
}
In my constructor of my Form I call the following to setup the logger.
Logger.InitLogger(LogError);
Then from any class in my project I can do the following:
Logger.LogError("error",new Exception("error), true);

Categories