New thread in singleton never finished - c#

I have simple singleton class:
namespace TestApp
{
public class MySingleton
{
static MySingleton()
{
}
private static readonly MySingleton instance = new MySingleton();
private bool threadFinished = false;
public bool IsReady = false;
private MySingleton()
{
Thread t = new Thread(MyAction);
t.Start();
while (!threadFinished)
Thread.Sleep(10);
}
public static MySingleton Instance
{
get { return instance; }
}
private void MyAction()
{
threadFinished = true;
}
}
}
When I'm trying instatiate this by:
var ir = MySingleton.Instance.IsReady;
it never ends - the while loop is infinite. Why? And how to run backround thread in singleton at constructor?

You're deadlocking. You're not allowed to call any methods from another thread before the static constructor is executed. Static constructor includes the static field initalizers too.
Since you're blocking the calling thread with a while loop, static field initialization will not complete and the new thread will neither be permitted to execute MyAction either.
Your code is almost identical to this code where Eric demonstrates the deadlock.
And to quote eric's comment from same answer why does it deadlock:
#Lieven: The static constructor must run no more than once and it
must run before the first call to any static method in the class. Main
is a static method, so the main thread calls the static ctor. To
ensure it only runs once, the CLR takes out a lock that is not
released until the static ctor finishes. When the ctor starts a new
thread, that thread also calls a static method, so the CLR tries to
take the lock to see if it needs to run the ctor. The main thread
meanwhile "joins" the blocked thread, and now we have our deadlock. –
Eric Lippert Jan 17 '12 at 14:28
To answer your question; Don't do that. You gain nothing by starting a thread and waiting for it. Just simply run the method synchronously.

This works. I am not a Singleton expert - if this violates any rules, someone please point it out. But this gets around the deadlock. I copied your code into a console app, if you're using it elsewhere, adjust appropriately.
namespace TestApp
{
class Program
{
static void Main(string[] args)
{
while (!MySingleton.Instance.IsReady)
Thread.Sleep(100);
Console.WriteLine("Done");
Console.Read();
}
}
public class MySingleton
{
static MySingleton()
{
}
private static readonly MySingleton instance = new MySingleton();
private static bool threadFinished = false;
public bool IsReady
{
get { return threadFinished; }
}
private MySingleton()
{
Thread t = new Thread(new ThreadStart(MyAction));
t.Start();
}
public static MySingleton Instance
{
get { return instance; }
}
static void MyAction()
{
threadFinished = true;
}
}

Have a look at the lock statement when you create an instance of your singleton to make it thread safe.
An example of how to use it in the singleton pattern can be found here: http://www.dofactory.com/net/singleton-design-pattern

Related

Avoid starting new thread with lock

Is this possible to lock method for one thread and force another to go futher rather than waiting until first thread finish? Can this problem be resolved with static thread or some proper pattern with one instance of mendtioned below service.
For presentation purposes, it can be done with static boolen like below.
public class SomeService
{
private readonly IRepository _repo;
public SomeService(IRepository repo)
{
_repo = repo;
}
private Thread threadOne;
public static bool isLocked { get; set; }
public void StartSomeMethod()
{
if(!isLocked)
{
threadOne = new Thread(SomeMethod);
isLocked = true;
}
}
public void SomeMethod()
{
while(true)
{
lots of time
}
...
isLocked = false;
}
}
I want to avoid situation when user clicked, by accident, two times to start and accidentailly second thread starts immediatelly after first finished.
You can use lock :)
object locker = new object();
void MethodToLockForAThread()
{
lock(locker)
{
//put method body here
}
}
Now the result will be that when this method is called by a thread (any thread) it puts something like flag at the beginning of lock: "STOP! You are not allowed to go any further, you must wait!" Like red light on crossroads.
When thread that called this method first, levaes the scope, then at the beginning of the scope this "red light" changes into green.
If you want to not call the method when it is already called by another thread, the only way to do this is by using bool value. For example:
object locker = new object();
bool canAccess = true;
void MethodToLockForAThread()
{
if(!canAccess)
return;
lock(locker)
{
if(!canAccess)
return;
canAccess = false;
//put method body here
canAccess = true;
}
}
Other check of canAccess in lock scope is because of what has been told on comments. No it's really thread safe. This is kind of protection that is advisible in thread safe singleton.
EDIT
After some discussion with mjwills I have to change my mind and turn more into Monitor.TryEnter. You can use it like that:
object locker = new object();
void ThreadMethod()
{
if(Monitor.TryEnter(locker, TimeSpan.FromMiliseconds(1))
{
try
{
//do the thread code
}
finally
{
Monitor.Exit(locker);
}
} else
return; //means that the lock has not been aquired
}
Now, lock could not be aquired because of some exception or because some other thread has already acuired it. In second parameter you can pass the time that a thread will wait to acquire a lock. I gave here short time because you don't want the other thread to do the job, when first is doing it.
So this solution seems the best.
When the other thread could not acquire the lock, it will go further instead of waiting (well it will wait for 1 milisecond).
Since lock is a language-specific wrapper around Monitor class, you need Monitor.TryEnter:
public class SomeService
{
private readonly object lockObject = new object();
public void StartSomeMethod()
{
if (Monitor.TryEnter(lockObject))
{
// start new thread
}
}
public void SomeMethod()
{
try
{
// ...
}
finally
{
Monitor.Exit(lockObject);
}
}
}
You can use a AutoResetEvent instead of your isLocked flag.
AutoResetEvent autoResetEvent = new AutoResetEvent(true);
public void StartSomeMethod()
{
if(autoResetEvent.WaitOne(0))
{
//start thread
}
}
public void SomeMethod()
{
try
{
//Do your work
}
finally
{
autoResetEvent.Set();
}
}

SynchronizationAttribute.SUPPORTED creates synchronization content

According to article class below is not thread safe:
I have code which gets into lock while according to my understanding has different synchronization content:
[Synchronization]
public class Deadlock : ContextBoundObject
{
public DeadLock Other;
public void Demo() { Thread.Sleep (1000); Other.Hello(); }
void Hello() { Console.WriteLine ("hello"); }
}
public class Test
{
static void Main()
{
Deadlock dead1 = new Deadlock();
Deadlock dead2 = new Deadlock();
dead1.Other = dead2;
dead2.Other = dead1;
new Thread (dead1.Demo).Start();
dead2.Demo();
}
}
It does and it is fine. But I decided to play with synchronization attributes by setting:
[Synchronization(SynchronizationAttribute.SUPPORTED)]
SUPPORTED means :
Joins the existing synchronization context if instantiated from
another synchronized object, otherwise remains unsynchronized
Since console application has no synchronization content I expect both object will have no synchronization object and should not get into deadlock. But I still have deadlock. Why?
Further have removed [Synchronization] attribute at all. Still have deadlock. What influence makes [Synchronization] attribute to object?
Here you are creating circular dependency between thread , that might lead you to stackoverflow exception , as you are not catching excpetion here you are might not able to view it. I suggest you make use of UnObservedExcpetion handler that will give you excpetion or try to handle excpetion in that same function by putting try, catch block.
To avoid this kind of situation you better make use of AutoResetEvent. below is sample code for the same.
public class MyThreadTest
{
static readonly AutoResetEvent thread1Step = new AutoResetEvent(false);
static readonly AutoResetEvent thread2Step = new AutoResetEvent(true);
void DisplayThread1()
{
while (true)
{
thread2Step.WaitOne();
Console.WriteLine("Display Thread 1");
Thread.Sleep(1000);
thread1Step.Set();
}
}
void DisplayThread2()
{
while (true)
{
thread1Step.WaitOne();
Console.WriteLine("Display Thread 2");
Thread.Sleep(1000);
thread2Step.Set();
}
}
void CreateThreads()
{
// construct two threads for our demonstration;
Thread thread1 = new Thread(new ThreadStart(DisplayThread1));
Thread thread2 = new Thread(new ThreadStart(DisplayThread2));
// start them
thread1.Start();
thread2.Start();
}
public static void Main()
{
MyThreadTest StartMultiThreads = new MyThreadTest();
StartMultiThreads.CreateThreads();
}
}

Using locks to access a method in 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() {
...
}

How to make a slightly modified AutoResetEvent class?

I need a synchronizing class that behaves exactly like the AutoResetEvent class, but with one minor exception:
A call to the Set() method must release all waiting threads, and not just one.
How can I construct such a class? I am simply out of ideas?
Martin.
So you have multiple threads doing a .WaitOne() and you want to release them?
Use the ManualResetEvent class and all the waiting threads should release...
Thank you very much for all your thougts and inputs which I have read with great interest. I did some more searching here on Stackoverflow, and suddenly I found this, whcih turned out to be just what I was looking for. By cutting it down to just the two methods I need, I ended up with this small class:
public sealed class Signaller
{
public void PulseAll()
{
lock (_lock)
{
Monitor.PulseAll(_lock);
}
}
public bool Wait(TimeSpan maxWaitTime)
{
lock (_lock)
{
return Monitor.Wait(_lock, maxWaitTime);
}
}
private readonly object _lock = new object();
}
and it does excactly what it should! I'm amazed that a solution could be that simple, and I love such simplicity. I'ts beautiful. Thank you, Matthew Watson!
Martin.
Two things you might try.
Using a Barrier object add conditionally adding threads too it and signaling them.
The other might be to use a publisher subscriber setup like in RX. Each thread waits on an object that it passes to a collection. When you want to call 'set' loop over a snapshot of it calling set on each member.
Or you could try bears.
If the event is being referenced by all threads in a common field or property, you could replace the common field or property with a new non-signaled event and then signal the old one. It has some cost to it since you'll be regularly creating new synchronization objects, but it would work. Here's an example of how I would do that:
public static class Example
{
private static volatile bool stopRunning;
private static ReleasingAutoResetEvent myEvent;
public static void RunExample()
{
using (Example.myEvent = new ReleasingAutoResetEvent())
{
WaitCallback work = new WaitCallback(WaitThread);
for (int i = 0; i < 5; ++i)
{
ThreadPool.QueueUserWorkItem(work, i.ToString());
}
Thread.Sleep(500);
for (int i = 0; i < 3; ++i)
{
Example.myEvent.Set();
Thread.Sleep(5000);
}
Example.stopRunning = true;
Example.myEvent.Set();
}
}
private static void WaitThread(object state)
{
while (!Example.stopRunning)
{
Example.myEvent.WaitOne();
Console.WriteLine("Thread {0} is released!", state);
}
}
}
public sealed class ReleasingAutoResetEvent : IDisposable
{
private volatile ManualResetEvent manualResetEvent = new ManualResetEvent(false);
public void Set()
{
ManualResetEvent eventToSet = this.manualResetEvent;
this.manualResetEvent = new ManualResetEvent(false);
eventToSet.Set();
eventToSet.Dispose();
}
public bool WaitOne()
{
return this.manualResetEvent.WaitOne();
}
public bool WaitOne(int millisecondsTimeout)
{
return this.manualResetEvent.WaitOne(millisecondsTimeout);
}
public bool WaitOne(TimeSpan timeout)
{
return this.manualResetEvent.WaitOne(timeout);
}
public void Dispose()
{
this.manualResetEvent.Dispose();
}
}
Another more lightweight solution you could try that uses the Monitor class to lock and unlock objects is below. However, I'm not as happy with the cleanup story for this version of ReleasingAutoResetEvent since Monitor may hold a reference to it and keep it alive indefinitely if it is not properly disposed.
There are a few limitations/gotchas with this implementation. First, the thread that creates this object will be the only one that will be able to signal it with a call to Set; other threads that attempt to do the same thing will receive a SynchronizationLockException. Second, the thread that created it will never be able to wait on it successfully since it already owns the lock. This will only be an effective solution if you have exactly one controlling thread and several other waiting threads.
public static class Example
{
private static volatile bool stopRunning;
private static ReleasingAutoResetEvent myEvent;
public static void RunExample()
{
using (Example.myEvent = new ReleasingAutoResetEvent())
{
WaitCallback work = new WaitCallback(WaitThread);
for (int i = 0; i < 5; ++i)
{
ThreadPool.QueueUserWorkItem(work, i.ToString());
}
Thread.Sleep(500);
for (int i = 0; i < 3; ++i)
{
Example.myEvent.Set();
Thread.Sleep(5000);
}
Example.stopRunning = true;
Example.myEvent.Set();
}
}
private static void WaitThread(object state)
{
while (!Example.stopRunning)
{
Example.myEvent.WaitOne();
Console.WriteLine("Thread {0} is released!", state);
}
}
}
public sealed class ReleasingAutoResetEvent : IDisposable
{
private volatile object lockObject = new object();
public ReleasingAutoResetEvent()
{
Monitor.Enter(this.lockObject);
}
public void Set()
{
object objectToSignal = this.lockObject;
object objectToLock = new object();
Monitor.Enter(objectToLock);
this.lockObject = objectToLock;
Monitor.Exit(objectToSignal);
}
public void WaitOne()
{
object objectToMonitor = this.lockObject;
Monitor.Enter(objectToMonitor);
Monitor.Exit(objectToMonitor);
}
public bool WaitOne(int millisecondsTimeout)
{
object objectToMonitor = this.lockObject;
bool succeeded = Monitor.TryEnter(objectToMonitor, millisecondsTimeout);
if (succeeded)
{
Monitor.Exit(objectToMonitor);
}
return succeeded;
}
public bool WaitOne(TimeSpan timeout)
{
object objectToMonitor = this.lockObject;
bool succeeded = Monitor.TryEnter(objectToMonitor, timeout);
if (succeeded)
{
Monitor.Exit(objectToMonitor);
}
return succeeded;
}
public void Dispose()
{
Monitor.Exit(this.lockObject);
}
}

AutoresetEvent and Singleton issue

Can someone please tell me what is wrong with the following code? Ideally it should start a thread first and then wait for the set event. Instead of that it does not start the thread and just get stuck on WaitOne().
I am curious to know what happened to the thread and why?
class Program
{
static void Main(string[] args)
{
Testing t = Testing.Instance;
Console.Read();
}
}
class Testing
{
private static AutoResetEvent evt = new AutoResetEvent(false);
public static Testing Instance = new Testing();
private Testing()
{
Create();
evt.WaitOne();
Console.WriteLine("out");
}
private void Create()
{
Console.WriteLine("Starting thread");
new Thread(Print).Start();
}
private void Print()
{
Console.WriteLine("started");
evt.Set();
}
}
EDIT:
So far, the description provided by #BrokenGlass makes sense. but changing the code to the following code allows another thread can access the instance methods without constructor being completed.(Suggested by #NicoSchertler).
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}
I suspect the root cause of this behavior is that the spawned thread cannot access the Print method until the constructor has finished executing - but the constructor never finishes executing because it is waiting on the signal that is triggered only from the Print method.
Replacing the evt.WaitOne() with a long Thread.Sleep() call confirms the same behavior - the constructor must finish running before any instance method of the object may execute from another thread.
The problem is that the second thread is created too early. I'm not sure why, but when started before the main program starts, it will not execute.
You should use the singleton pattern in its original version. This will work.
private static Testing _Instance;
public static Testing Instance
{
get
{
if (_Instance == null)
_Instance = new Testing();
return _Instance;
}
}
Additionally, you should not make the evt variable static. The instance variable should be the only static member of a singleton class in most cases.
My guess would be an issue with the relative timing of the static field initialization. Try initializing evt in the constructor of Testing instead:
private static AutoResetEvent evt;
public static Testing Instance = new Testing();
private Testing()
{
evt = new AutoResetEvent(false);
Create();
evt.WaitOne();
Console.WriteLine("out");
}
I should note this is really just a guess- I'd have thought this code would work fine.

Categories