【问题标题】:How to forcefully leave the serialPort_DataReceived event?如何强制退出 serialPort_DataReceived 事件?
【发布时间】:2014-01-30 10:08:29
【问题描述】:

这是我下面的程序,它从端口读取数据以获取呼叫者 ID 数据。但我想一旦它得到它应该停止监听端口并读取更多数据的数字。并执行异常编写的任务。但是,即使当我强行尝试退出事件并抛出异常时它也不起作用,并且当我设置超时时它也不会离开......我该怎么办请告诉我。

            bool _continue = true;
            string message = string.Empty;
            string number = string.Empty;
            private void serialPort_DataNewReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                try
                {
                    if (_continue)
                    {
                        SerialPort sp = (SerialPort)sender;
                        message = sp.ReadExisting();
                        if (message.Contains("MESG"))
                        {
                            string[] strFirstStep = Regex.Split(message, "\r\nNMBR =");
                            string[] strLastStep = Regex.Split(strFirstStep[1], "\r\n");
                            number = strLastStep[0];
                            _continue = false;

                        }
                    }
                    else throw new TimeoutException();
                }
                catch (TimeoutException t)
                {
                    bw = new BackgroundWorker();
                    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                    bw.RunWorkerAsync();
                }
            }

【问题讨论】:

    标签: c# port


    【解决方案1】:

    为什么DataReceived会出现超时异常?也许你需要类似的东西:

    bool _continue = true;
    string message = string.Empty;
    string number = string.Empty;
    
    private void serialPort_DataNewReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        // stop listening (by ignoring call)
        if (!_continue)
            return;
    
        // proceed
        SerialPort sp = (SerialPort)sender;
        message = sp.ReadExisting();
        if (message.Contains("MESG"))
        {
            string[] strFirstStep = Regex.Split(message, "\r\nNMBR =");
            string[] strLastStep = Regex.Split(strFirstStep[1], "\r\n");
            number = strLastStep[0];
            _continue = false;
    
            // do a work if number is received
            bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
            bw.RunWorkerAsync();
        }
    

    要处理超时(当您有一段时间没有收到数据时),您可以创建一个计时器,该计时器将在收到数据时重置。如果定时器没有及时重置,那么它的tick事件就会触发,也就是——超时。

    【讨论】:

    • 我只希望一旦我收到号码就不想再监听端口并使用该号码执行后台任务...
    • do not want to listen any more 听起来你必须关闭 com-port。
    • 好的,下一个问题:为什么需要BackgroundWorker?您的DataReceived 事件已经在某个(UI 除外)线程中,只需完成您的工作(调用bw_DoWork),一旦完成,关闭com-port。或者之前关闭它。
    • 实际上在通话期间我想在任务栏通知程序中显示数字并带有一些消息...这是我想要实现的,所以我有一些代码可以运行任务栏..跨度>
    【解决方案2】:

    你需要从串口对象中移除事件

    serialPort.DataReceived -= serialPort_DataNewReceived;
    

    【讨论】:

    • 你的意思是在 catch 我应该编写你的语法来删除事件并执行其他任务,但是接下来当调用回来时我需要重新附加它..
    • 我设置了 100 毫秒的串口超时,为什么不允许它跳过线程并跳转到异常任务..
    • DataReceived 事件只有在串口有数据时才会被调用。
    • 当您尝试从串行端口读取数据而没有这样的事件时超时有效:serialPort.Read
    猜你喜欢
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2011-05-17
    • 2015-04-29
    • 1970-01-01
    相关资源
    最近更新 更多