许多线程正在访问这段代码
// All code is from same class
public void ExecuteCommand(IAsciiCommand command, IAsciiCommandSynchronousResponder responder)
{
lock (commander)
{
if (commander.IsConnected)
{
commander.ExecuteCommand(command, responder);
}
}
}
public void Disconnect()
{
var tmp = commander.IsConnected;
commander.Disconnect();
if (commander.IsConnected != tmp && !commander.IsConnected)
{
OnPropertyChanged("IsConnected");
}
}
最终我得到了这个:
这怎么可能,该线程被访问到if语句,其条件返回false?我该如何解决?
答案 0 :(得分:2)
这种情况正在发生,因为检查和调用缺少原子性。以下是可能导致异常的一系列事件:
true
,进入if
块Disconnect
if
条件内。但是,该命令不再连接您可以通过在commander
内锁定Disconnect()
来解决此问题。
public void Disconnect()
{
bool doEvent;
lock(commander) {
var tmp = commander.IsConnected;
commander.Disconnect();
doEvent = (commander.IsConnected != tmp && !commander.IsConnected)
}
// Run OnPropertyChanged outside the locked context
if (doEvent)
{
OnPropertyChanged("IsConnected");
}
}
答案 1 :(得分:1)
您需要锁定静态对象。现在,您根据正在使用的对象(commander
)创建单独的锁。试试这个:
public class WhatEverClassHasTheExecuteCommandMethod
{
private static object _lock = new object();
public void ExecuteCommand(IAsciiCommand command, IAsciiCommandSynchronousResponder responder)
{
lock (_lock)
if (commander.IsConnected)
commander.ExecuteCommand(command, responder);
}
}
答案 2 :(得分:1)
如果您在断开连接时未锁定,则完全有可能获得竞争条件。基本解决方案是在Disconnect
方法中添加一个锁:
public void Disconnect()
{
lock (commander)
{
var tmp = commander.IsConnected;
commander.Disconnect();
if (commander.IsConnected != tmp && !commander.IsConnected)
OnPropertyChanged("IsConnected");
}
}