死锁lock()方法 [英] Deadlocking lock() method
问题描述
我正面临僵局,我的代码结构与此类似:
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);
}
}
}
但是使用相同的代码,我只是像这样修改了UpdateControl方法:
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
}
}
这很好。是什么问题?
推荐答案
问题几乎可以肯定是,您正在后台线程中获取锁,然后调用 Control.Invoke
,并调用一个试图获取相同锁的委托(在UI线程上)。它不能这样做,因为另一个线程持有该锁-并且在等待UI操作完成时将一直持有该锁。
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.
诚然,没有锁定在您已发布的UpdateControl方法中,但我怀疑这不是完整的代码-并且您没有显示正在使用 AddItem
或的位置RemoveItem
。
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 AddItem
or RemoveItem
.
我注意到,顺便说一句,GetThreadHandler()并不是线程安全的-对我来说似乎是个错误。
I note that GetThreadHandler() isn't thread-safe, by the way - that looks like a bug to me...
这篇关于死锁lock()方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!