Using locks to access a method in C# - c#

I have a method A which call another method B. Upon clicking on a button, method A is called which in turn calls method B. However, when 2 users click on the button simultaneously, I want only one user to access method B while the other waits for method B to complete. I thought of doing it this way:
private static Object _Lock = new Object();
private void A(){
lock(_Lock){
B();
}
}
The users are on different machines. The project is a web site.
But I think this is not correct. How can I improve the above code so that it is the proper way to work?

I agree with #Torestergaard, you should keep the lock as slim as possible. Therefor if taking the code sample provided above by #Rebornx and modifying it a bit you can use something like below example:
public class Program
{
public static void Main()
{
LockSample lockSampleInstance = LockSample.GetInstance();
lockSampleInstance.MethodA();
}
}
public class LockSample
{
private static readonly LockSample INSTANCE = new LockSample();
private static Object lockObject = new Object();
public static LockSample GetInstance()
{
return INSTANCE;
}
public void MethodA()
{
Console.WriteLine("MethodA Called");
MethodB();
}
private void MethodB()
{
lock(lockObject)
{
Console.WriteLine("MethodB Called");
}
}
}
Hope it will help,
Liron

Here is a simple program, I used single ton pattern. You can achieve the locking by using "Monitor" also.
public class Program
{
public static void Main()
{
LockSample lockObject = LockSample.GetInstance();
lock(lockObject)
{
lockObject.MethodA();
}
}
}
public class LockSample
{
private static LockSample _Lock;
public static LockSample GetInstance()
{
if(_Lock == null)
{
_Lock = new LockSample();
}
return _Lock;
}
public void MethodA()
{
Console.WriteLine("MethodA Called");
MethodB();
}
private void MethodB()
{
Console.WriteLine("MethodB Called");
}
}

Generally you should keep you lock as slim as possible, so dependent on what you do then it might make sense to move the lock statement into method B only guarding the resource that doesn't support multiple parallel users.
But generally there is nothing wrong with your example.

You can declare the method B with this attribute:
[MethodImpl(MethodImplOptions.Synchronized)]
public void B() {
...
}

Related

Awaiting on a task from a different class

I have a singleton class and a property that gets set from another class (class b), no problem. I want a different class (class a) to wait indefinitely until the property in the singleton class transitions true. I want the most efficient way possible of doing this, so I felt tasks were ideal, but I can't effectively put all of the pieces together. I don't want to continue to poll and sleep thread.sleep.
public class A
{
public static void Main(string[] args)
{
if(!Monitor.Instance.HasChanged)
{
//await until the task in the Monitor class is complete
}
}
}
public class Monitor
{
private static Monitor instance;
private bool _hasChanged;
private Monitor() { }
public static Monitor Instance
{
get
{
if (instance == null)
{
instance = new Monitor();
}
return instance;
}
}
public bool HasChanged
{
get
{
return _hasChanged;
}
set
{
_hasChanged = value;
if (_hasChanged)
{
//kick off a task
}
}
}
}
public class B
{
private static readonly Monitor _instance;
public void DoSomething()
{
Monitor.Instance.HasChanged = true;
}
}
I would use a TaskCompletionSource for this. You would do something like:
public class Monitor
{
private TaskCompletionSource<bool> _changedTaskSource = new TaskCompletionSource<bool>();
public Task HasChangedTask => _changedTaskSource.Task;
public bool HasChanged
...
set
{
...
_changedTaskSource.TrySetResult(true);
}
}
This sets up a task completion source and completes the task when the value changes. You would wait on it like so:
await Monitor.Instance.HasChangedTask;
One thing that is not clear from your question and you will need to address is resetting the task. To do so, just re-create the TaskCompletionSource.

what object type/instance to use for synchronization

I have seen different variations of objects used when acquiring a lock
A static private object
public class MyClass
{
private static object syncBlock = new object();
private void MyMethod()
{
lock (syncBlock)
{
}
}
}
A class level private object
public class MyClass
{
private object syncBlock = new object();
private void MyMethod()
{
lock (syncBlock)
{
}
}
}
using the type itself
public class MyClass
{
private void MyMethod()
{
lock (typeof (MyClass))
{
}
}
}
using this:
public class MyClass
{
private void MyMethod()
{
lock (this)
{
}
}
}
Can someone elaborate what are the pro/cons of each of these and if one should be preferred over others in a given scenario.
Don't use lock(this).
Don't use lock(typeof(MyClass)) either.
As for static vs instance, it depends on what is appropriate for you. If you use a static private object, then all instances of your class will share the lock. If you use a private object that is not static, then each instance will have its own lock. So there is no pro/cons, it depends on what you need.

C# how to implement "singleton" method

We all know about the singleton pattern.
How do you implement a singleton "method"? - a method that is called only once and any other call will do nothing.
I can think a few ways (including Lazy - if (!.IsValueCreated) {... value.method();}) but how would you implement it?
I don't think so there is something like a singleton method.
If you want your method to do execute the block of code only once then you can do that. This can be done in several ways, one of them could be as follows-
public class Foo
{
private static bool _isInitialied;
public void Initialize()
{
if(_isInitialied)
return;
//TODO: Initialization stups.
_isInitialied = true;
}
}
You could achieve this using actions:
public class Test
{
private Action _action;
private void DoSomething()
{
// Do something interesting
_action = DoNothing;
}
private void DoNothing()
{
}
public Test()
{
_action = DoSomething;
}
public void Call()
{
_action();
}
} // eo class Test

Method lock in c#

I have one class with these three methods. This class is used by many threads.
I would like the Method1 to wait, if Method2 and/or Method3 are running in any threads.
Any suggestions?
public class Class1
{
public static void Method1()
{
Object lockThis = new Object();
lock (lockThis)
{
//Body function
}
}
public static void Method2()
{
//Body function
}
public static void Method3()
{
//Body function
}
}
If I understood correctly, you need something like this:
static object lockMethod2 = new object();
static object lockMethod3 = new object();
public static void Method1()
{
lock (lockMethod2)
lock (lockMethod3)
{
//Body function
}
}
public static void Method2()
{
lock (lockMethod2)
{
//Body function
}
}
public static void Method3()
{
lock (lockMethod3)
{
//Body function
}
}
This allows method3 to execute if method2 is running and vice versa, while method1 must wait for both. Of course, method2 and 3 will not run while 1 is running.
The current implementation of your lock is completely useless, because every thread will lock on a different object.
Locking is usually done with a readonly field that is initialized only once.
Like this, you can easily lock multiple methods:
public class Class1
{
private static readonly object _syncRoot = new object();
public static void Method1()
{
lock (_syncRoot)
{
//Body function
}
}
public static void Method2()
{
lock (_syncRoot)
{
//Body function
}
}
public static void Method3()
{
lock (_syncRoot)
{
//Body function
}
}
}
I would suggest a ReaderWriterLockSlim (http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx)
Similar to read operations, Method 2 and Method3 may occur in parallel, while Method1 (like a write operation) would need to wait for those to finish.
It's not the regular read/write concurrency situation, but the logic is similar.
public class Class1
{
private ReaderWriterLockSlim methodLock = new ReaderWriterLockSlim();
public static void Method1()
{
methodLock.EnterWriteLock();
try
{
//Body function
}
finally
{
methodLock.ExitWriteLock();
}
}
public static void Method2()
{
methodLock.EnterReadLock();
try
{
//Body function
}
finally
{
methodLock.ExitReadLock();
}
}
public static void Method3()
{
methodLock.EnterReadLock();
try
{
//Body function
}
finally
{
methodLock.ExitReadLock();
}
}
}
If you are multi-threading then the lock has to be accessible to all threads. Therefore, in this case, your locks needs to be static for the static methods to see it.
Your current setup will make a new lock object for each thread. Therefore, providing now synchronization.

C# Singleton pattern with triggerable initialization

I need a singleton that:
is lazy loaded
is thread safe
loads some values at construction
those values can be queried at any time
the initialization MAY happen at some precise time, before the querying begins - so I must be able to trigger it from the outside somehow. Of course, triggering multiple times should only do the initialization once.
I use .NET 3.5.
I've started with Jon Skeet's implementation (5th version) using a static subclass:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
This ticks almost all the boxes, except the "trigger initialization from outside". Since the actual initialization happens inside the ctor, it can't happen more than once.
How can this be accomplished?
The singleton will be used like this:
public static void Main(){
//do stuff, singleton should not yet be initialized.
//the time comes to initialize the singleton, e.g. a database connection is available
//this may be called 0 or more times, possibly on different threads
Singleton.Initialize();
Singleton.Initialize();
Singleton.Initialize();
//actual call to get retrieved values, should work
var retrieveVals = Singleton.Instance.Values;
}
Seems like you could do:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton(bool loadDefaults)
{
if (loadDefaults)
Values = new[]{"quick", "brown", "fox"};
else
Values = new[]{"another", "set", "of", "values"};
}
public static Singleton Instance { get { return Nested.instance; } }
public static void Initialize() {
Nested.Initialize();
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton(true);
private static object instanceLock = new object();
private static bool isInitialized = false;
public static void Initialize() {
lock(instanceLock) {
if (!isInitialized) {
isInitialized = true;
instance = new Singleton(false);
}
}
}
}
}
Or to create a single instance that will be updated:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
public static Singleton Instance { get { return Nested.instance; } }
private static object instanceLock = new object();
private static bool isInitialized = false;
public static void Initialize() {
lock(instanceLock) {
if (!isInitialized) {
isInitialized = true;
Instance.Values = new[]{"another", "set", "of", "values"};
}
}
}
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
And the third variation based on your immutable comment and removal of Nested class comment:
public sealed class Singleton
{
IEnumerable<string> Values {get; private set;}
private Singleton()
{
Values = new[]{"quick", "brown", "fox"};
}
private static Singleton instance;
private static object instanceLock = new object();
public static Singleton Instance {
get {
Initialize();
return instance;
}
}
public static void Initialize() {
if (instance == null) {
lock(instanceLock) {
if (instance == null)
instance = new Singleton();
}
}
}
}
The first idea I had was to just use a throwaway variable assigned to the singleton's instance, which would (probably?) trigger the initialization
static Main()
{
var unused = Singleton.Instance;
//this should initialize the singleton, unless the compiler optimizes it out.
//I wonder if the compiler is smart enough to see this call has side effects.
var vals = Singleton.Instance.Values;
}
... but programming by side-effects is something I try hard to avoid, so let's make the intention a bit clearer.
public class Singleton {
public static void Initialize() {
//this accesses the static field of the inner class which triggers the private Singleton() ctor.
Instance._Initialize();
}
private void _Initialize()
{ //do nothing
}
[the rest as before]
}
so the usage would be:
static Main()
{
//still wondering if the compiler might optimize this call out
Singleton.Initialize();
var vals = Singleton.Instance.Values;
}
Btw this would also work:
static Main()
{
var vals = Singleton.Instance.Values;
}
Compiler optimization aside, I think this deals with all the requirements.
You can set up an Initialize method that can be fired from outside, if you need the initialize to happen later, but if the values are different on each time it is fired, then it cannot be static, which violates the Singleton pattern.
Based on your example, which has no variables, I assume you are just delaying when the initialization happens (routine rather than constructor), but your question suggests you want different values, but if multiple initializations happen close together, it only initializes once, so I am a bit confused on this.
I am not sure you need a Singleton only implmentation, but cannot fully answer without information on whether or not the Initialize() runs the same code every time or has some type of variable nature.
You can use double-checked locking pattern. Just add following code in you Singleton class:
public sealed class Singleton
{
..........................
private static object locker = new object();
private static bool initialized = false;
public static void Initialize() {
if (!initialized){
lock(locker) {
if (!initialized){
//write initialization logic here
initialized = true;
}
}
}
}
.......................
}
You can do something like this
public sealed class Singleton
{
IEnumerable<string> Values { get; set; }
private Singleton()
{
Console.WriteLine("-- Private Singleton constructor");
Values = new[] { "quick", "brown", "fox" };
}
public static Singleton Instance
{
get
{
Console.WriteLine("- Singleton Instance");
return Nested.instance;
}
}
public static void Initialize()
{
Console.WriteLine("- Singleton Initialize");
Nested.Initialize();
}
internal class Nested
{
private static object syncRoot = new object();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
Console.WriteLine("-- Static Nested constructor");
}
internal static readonly Singleton instance = new Singleton();
internal static void Initialize()
{
lock (syncRoot)
{
Console.WriteLine("-- Locked");
Console.WriteLine("--- Nested Initialize");
Console.WriteLine("-- Unlocked");
}
}
}
}
Usage
class Program
{
static void Main(string[] args)
{
var i = Singleton.Instance;
i = Singleton.Instance;
Console.WriteLine("-----");
Singleton.Initialize();
Singleton.Initialize();
Singleton.Initialize();
Console.Read();
}
}
Which outputs
- Singleton Instance
-- Private Singleton constructor
-- Static Nested constructor
- Singleton Instance
-----
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
- Singleton Initialize
-- Locked
--- Nested Initialize
-- Unlocked
public class Singleton<T> where T : class, new()
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
throw new Exception("singleton needs to be initialised before use");
}
return instance;
}
}
public static void Initialise(Action<T> initialisationAction)
{
lock(typeof(Singleton<T>))
{
if (instance != null)
{
return;
}
instance = new T();
initialisationAction(instance);
}
}
}

Categories