工作与RS232使用多线程

本文关键字:多线程 RS232 工作 | 更新日期: 2023-09-27 18:03:46

我试图编写一个类,表示通过RS232连接与设备通信。这个设备既可以被读取也可以被写入,这可以由多个线程来完成。

到目前为止,我选择使类成为单例类,因为只有一个连接到设备应该永远存在是有意义的。我还实现了两个接口IDataProviderIDataConsumer。这些简单地定义了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;
    }
}

我现在的问题是我如何使这个线程安全。我假设在ReadDataWriteData中,我将锁定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端口发送和/或接收信息来执行队列,然后继续处理下一个排队的消息。

这有助于简化代码流,并有助于防止死锁。所有实际访问RS232资源的代码都只在一个线程(您的队列服务线程)上执行。对于所有其他线程,它们只需要将它们的请求发布到队列中——这是一个非常快的操作,然后检查它们的响应。

实现这个的一种方法是:

_myMessageQueue = new ConcurrentQueue<Rs232Message>();

将新消息发送到消息队列:

_myMessageQueue.Enqueue( message );

,您使用:

检索队列消息
bool isOk = _myMessageQueue.TryDequeue( out message );