I’m facing a deadlock, my code structure is similar to this:
private delegate void UpdateControlDelegate(string value); public void UpdateControl(string value) { if (txtAddress.InvokeRequired) { txtAddress.Invoke(new UpdateControlDelegate(UpdateControl), value); } else { txtAddress.Text = value; // This is in GroupBox1 txtValue.Text = value; // This is in GroupBox2 } } class ThreadHandler { List<string> _list = new List<string>(); object _criticalSection = new object(); public ThreadHandler() { new Thread(new ThreadStart(Run)).Start(); } public static ThreadHandler _threadHandler = null; public static ThreadHandler GetThreadHandler() { if (_threadHandler == null) { _threadHandler = new ThreadHandler(); } return _threadHandler; } public void Run() { while (true) { // some code lock (_criticalSection) { foreach (string str in _list) { // some Code } } // some code Thread.Sleep(SomeTime); } } public void AddItem(string item) { lock (_criticalSection) { _list.Add(item); } } public void RemoveItem(string item) { lock (_criticalSection) { _list.Remove(item); } } }
But using the same code, I just modified the UpdateControl method like this:
private delegate void UpdateControlDelegate(string value); public void UpdateControl(string value) { if (InvokeRequired) { BeginInvoke(new UpdateControlDelegate(UpdateControl), value); } else { txtAddress.Text = value; // This is in GroupBox1 txtValue.Text = value; // This is in GroupBox2 } }
This is working fine. What is the problem?
The problem is almost certainly that you’re acquiring the lock within a background thread, then calling
Control.Invoke, and invoking a delegate (on the UI thread) which tries to acquire the same lock. It can’t do that, because the other thread holds the lock – and will keep holding the lock while it waits for the UI operation to complete.Admittedly there’s no locking within the UpdateControl method you’ve posted, but I suspect that’s not the complete code – and you haven’t shown where you’re using
AddItemorRemoveItem.I note that GetThreadHandler() isn’t thread-safe, by the way – that looks like a bug to me…