锁弄乱了串行端口句柄

本文关键字:句柄 串行端口 乱了 锁弄 | 更新日期: 2023-09-27 18:16:23

我有一个关于概念设计使用系统的问题。定时器和线程。

考虑以下伪代码(它是在c#中,但因为我问的是概念,我没有检查语法的准确性)

class exam{
    private Serialport sp;
    private readonly object lckObj = new object();
    System.Timer timer;
    public exam()
    {
        // actually I think this lock is not needed as
        // the object gets created on thread creation... 
        // a yay-nay on this would be cool too, I figure it
        // can't hurt to lock
        lock(lckObj) 
        {
            // do stuff
            sp = new Serialport(params);
            sp.DataRecieved += sp_dataRec;
            timer = new system.Timer(someNumber);
            timer.Elapsed += timeElap;
            timer.Enabled = true;
            // also from my understanding in how enabled 
            // works, this is redundant and I can remove
            timer.Start(); 
        }
    }
    private void timeElap()
    {
        lock(lckObj)
        {
            if(sp.Closed) sp.Open();
        }
    }
    private void sp_dataRec()
    {
        lock(lckObj)
        {            
           //do stuff to process message
           // set success bool
           bool success = outcomeOfProcessing;
           callResponse(success);
        }
    }
    private void callResponse(bool success)
    {   
        if(!sp.IsOpen) sp.Open();
        // logic to assemble response hinged on success
        sp.Write("something");
    }
}

我要做的是让计时器通过,每隔几秒钟检查一次,以确保端口没有关闭。这是因为"某些东西"不知道是什么关闭端口-通过附加端口监视器发现这一点,它只是随机弹出关闭。没有错误弹出或任何东西(没有定时器抑制错误,我正在寻找添加定时器)。不知道为什么会发生这种情况(也从来没有在代码中I .Close();

然而,当我思考这个槽我现在担心,如果我锁定检查串行端口检查状态,以及锁定它发送消息返回-这将抑制我的数据接收句柄,或者它仍然会相应地排队

例如,我锁定串行端口以检查状态,并且只是稍微错过可能在字节上我的数据在pop中,而不是获得

.1234 .

1234。

注意点是开始/停止字节

编辑:我忘了说我的另一个担心是系统。串口干扰定时器抑制错误

Edit2:我从callResponse中删除了锁-当我再次查看它时,对响应的调用将在已经锁定的方法中-所以它应该是线程安全的-正确吗?

锁弄乱了串行端口句柄

SerialPort缓冲区数据。在调用接收到的事件处理程序之前,底层控件已经从串行端口读取数据并将其存储在内部缓冲区中。这个锁不会引起问题,除非你持有它的时间太长以至于数据缓冲区被填满。

那就是说,我必须重复我在评论中说过的话:你提出的解决方案不能可靠地工作。如果您的程序外部的某些东西正在异步禁用串行端口,那么无论您的程序处于何种状态,它都可能在任何时候发生。您有一个一秒钟的计时器,用于检查端口是否关闭,如果关闭,则重新打开它。这可能会在"大多数情况下"解决问题,但不能保证端口在重新打开后不会立即关闭,或者在程序发送或接收数据的过程中关闭端口。请记住:您的代码并不执行实际的发送或接收,而是读取或写入由底层SerialPort控件管理的缓冲区。

你真的需要找出是什么原因导致串行端口被关闭,并防止这种情况发生。这是使您的程序可靠的唯一方法。