I have a multi-threaded program (C#) where I have to share global static variables between threads that may take some time to execute (sending data request to another system using WCF). The problem is that using the lock statement does not seem to guarantee mutual exclusion when it's declared outside of the ThreadPool.
static void Main(string[] args)
{
public static int globalVar = 0;
public object locker;
System.Timers.Timer timer1 = new System.Timers.Timer(1000);
timer1.Elapsed += new ElapsedEventHandler(onTimer1ElapsedEvent);
timer1.Interval = 1000;
timer1.Enabled = true;
System.Timers.Timer timer2 = new System.Timers.Timer(500);
timer2.Elapsed += new ElapsedEventHandler(onTimer2ElapsedEvent);
timer2.Interval = 500;
timer2.Enabled = true;
}
public void onTimer1ElapsedEvent(object source, ElapsedEventArgs e)
{
lock (locker) {
ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
{
globalVar = 1;
Console.WriteLine("Timer1 var = {0}", globalVar);
}));
}
}
public void onTimer2ElapsedEvent(object source, ElapsedEventArgs e)
{
lock (locker) {
ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
{
globalVar = 2;
Thread.Sleep(2000); // simulates a WCF request that may take time
Console.WriteLine("Timer2 var = {0}", globalVar);
}));
}
}
So the lock does not work and the program can prints: Timer2 var = 1
Putting the the lock statement inside the ThreadPool seems to resolve the problem.
public void onTimer1ElapsedEvent(object source, ElapsedEventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
{
lock (locker) {
globalVar = 1;
Console.WriteLine("Timer1 var = {0}", globalVar);
}
}));
}
public void onTimer2ElapsedEvent(object source, ElapsedEventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(state =>
{
lock (locker) {
globalVar = 2;
Thread.Sleep(2000); // simulates a WCF request that may take time
Console.WriteLine("Timer2 var = {0}", globalVar);
}
}));
}
However, I don't uderstand the difference between the two approaches and why it does not produce the same behaviour.
Also, the 2nd approach resolves the mutual exclusion problem but the timer1 thread will always have to wait for the timer2 to finish his lock statement (which takes time), so the multi-threading concept does not work anymore in my program. I want to know what's the best solution of having multi threading doing their job in parallel with using shared variables ?