我正在尝试编写一个代表与设备通过RS232连接进行通信的类。这个设备可以被读取和写入,这可以由多个线程完成。使用多线程使用的RS232?
到目前为止,我选择将该类设置为单例类,因为它有意义,只有一个连接到设备应该永远存在。我还实施了两个接口IDataProvider
和IDataConsumer
。这些只是定义了方法Boolean ReadData(out Object readData, params Object[] args)
和WriteData(Object inData, params Object[] args)
。随着界面我也写了RS232Device
。这实现了将端口Open()
,Close()
,Read()
和Write()
的方法。
以下是我的课程概述。
public class DeviceIO : RS232Device, IDataProvider, IDataConsumer
{
public static DeviceIO Instance { get { return lazyInstance.Value; } }
private static readonly Lazy<DeviceIO> lazyInstance
= new Lazy<DeviceIO>(() => new DeviceIO());
private DeviceIO() : base() {}
public void ConfigurePort(SerialPortConfig inConfig)
{
Configure(inConfig);
}
public Boolean ReadData(out Object readData, params Object[] args)
{
readData = null;
return false;
}
public Boolean WriteData(Object inData, params Object[] args)
{
return false;
}
}
我现在的问题是我如何使这个线程安全。我会假设在ReadData
和WriteData
之内,我会锁定Object
的某个实例。这就是我需要做的一切吗?基本上就像下面的修改一样?
我可以将下面的Instance
分配给各种线程,并且在两个线程可能尝试同时写入设备时没有任何问题吗?
public class DeviceIO : RS232Device, IDataProvider, IDataConsumer
{
public static DeviceIO Instance { get { return lazyInstance.Value; } }
private static readonly Lazy<DeviceIO> lazyInstance
= new Lazy<DeviceIO>(() => new DeviceIO());
private static readonly Object Schlage = new Object();
private DeviceIO() : base() {}
public void ConfigurePort(SerialPortConfig inConfig)
{
lock(Schlage)
{
Configure(inConfig);
}
}
public Boolean ReadData(out Object readData, params Object[] args)
{
lock (Schlage)
{
readData = null;
return false;
}
}
public Boolean WriteData(Object inData, params Object[] args)
{
lock (Schlage)
{
return false;
}
}
}
这是正确的。注意:你的'Schlage'变量不一定是'static'。 –
还有一个问题,大多数情况下,当你试图查询串口设备时,你首先向RS232写入数据,然后读取一行数据。如果我输入'ReadData'方法并获得一个锁,我可以调用'WriteData'而不是自己死锁吗? – KDecker
一旦锁定建立,'lock'只会阻止** OTHER **线程进入。从**相同的**线程内,从ReadData()到WriteData()不会阻塞,并且不会导致问题。 –