工作与RS232使用多线程
本文关键字:多线程 RS232 工作 | 更新日期: 2023-09-27 18:03:46
我试图编写一个类,表示通过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;
}
}
}
我建议通过实现消息队列模式来更好地满足这种类型的场景。在这里,任何需要使用RS232功能的代码都将请求排队到队列中,并等待应答或反应。与此同时,只有一个线程将服务于该队列的业务端,一次一个地将它们从队列中取出,通过从RS232端口发送和/或接收信息来执行队列,然后继续处理下一个排队的消息。
这有助于简化代码流,并有助于防止死锁。所有实际访问RS232资源的代码都只在一个线程(您的队列服务线程)上执行。对于所有其他线程,它们只需要将它们的请求发布到队列中——这是一个非常快的操作,然后检查它们的响应。
实现这个的一种方法是:
_myMessageQueue = new ConcurrentQueue<Rs232Message>();
将新消息发送到消息队列:
_myMessageQueue.Enqueue( message );
,您使用:
检索队列消息bool isOk = _myMessageQueue.TryDequeue( out message );