Reputation: 77
My app kept freezing with no reason so I simplified the code until I contained the problem. Apparently having two synclock (one in a simple sub and another in a timer) caused it. This is the simplified code:
String var1 = "";
String var2 = "";
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(test_sub);
thread.Start();
}
private void test_sub()
{
lock (var1)
{
Thread.Sleep(1000000);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
lock (var2){}
}
Timer 1 is enabled by default with 1s delay between ticks. As soon as button1 is press, the UI freezes. Can anyone please explain what's causing this weird behavior and what can be done about it? Thanks!
Upvotes: 0
Views: 301
Reputation: 7350
Your problem is not in the Thread, or in the lock per se.
The problem is in the objects used to lock: the two locks are locking on the empty string, which is optimized to use the String.Empty
instance.
So your code reads:
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(test_sub);
thread.Start();
}
private void test_sub()
{
lock (String.Empty)
{
Thread.Sleep(1000000);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
lock (String.Empty){}
}
Which is going to lock the UI thread as soon as timer1_Tick is entered, because the timer (running on the UI thread) is going to lock the same object instance as the test_sub
(running on a separate thread).
To ensure two locks are used, you should declare your lock objects like this:
private readonly object _lock1 = new object();
private readonly object _lock2 = new object();
This guarantees no external locking happens on the same objects, and that the two lock objects are distinct instances.
Upvotes: 5