【问题标题】:Serial port worker thread freezing randomly串口工作线程随机冻结
【发布时间】:2017-02-10 15:08:44
【问题描述】:

我通过以下代码调用我的后台工作人员:

private void UpdateDataTimer_Tick(object sender, EventArgs e)
{
    if (!serialPortWorker.IsBusy)
    {
        serialPortWorker.RunWorkerAsync();
    }
}

我的DoWork事件如下:

private void serialPortWorker_DoWork(object sender, DoWorkEventArgs e)
{
    //Configures serial port
    connection.BaudRate = 19200;
    connection.DataReceived += new SerialDataReceivedEventHandler(DataReceivedEvent);

    //Sends the commands for opening diagnostics
    string[] init_commands = { "STRING", "STRING", "STRING", "STRING", "STRING" };
    foreach (string command in init_commands)
    {
        connection.WriteLine(command + connection.NewLine);
        Thread.Sleep(1000);
    }

    const string constant_message_section = "G03";
    string[] command_list = { "62", "64", "5C" };

    //Writes all commands to all radio addresses
    foreach (int address in radioAddresses)
    {
        foreach (string command in command_list)
        {
            for (int i = 0; i < MAX_ATTEMPTS; i++)
            {
                connection.WriteLine(constant_message_section + address.ToString("X4") + command);
                Thread.Sleep(500);
            }
        }
    }

    Thread.Sleep(1000); //Give a little time for all responses to come in
}

由于某种原因,在调用了几百次UpdateDataTimer_Tick 事件后,它不会再运行serialPortWorker。我在if (!serialPortWorker.IsBusy) 放了一个调试器,它表明serialPortWorker 仍然很忙。它一定挂在DoWork 事件的某个地方,对吧?任何想法为什么?

有兴趣的可以看看数据接收事件如下:

public void DataReceivedEvent(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string receive = sp.ReadLine();

    try
    {
        Debug.Logger.WriteToDebug("Data Received Serial Port: " + receive);
    }
    catch { }

    try
    {
        int unit_address = Int32.Parse(receive.Substring(1, 4), System.Globalization.NumberStyles.HexNumber);

        if (radioAddresses.Contains(unit_address))
        {
            int radio_index = radioAddresses.IndexOf(unit_address) + 1;
            int max_index = radio_index * 3;

            integrityMonitor[radio_index] = DateTime.Now; //Last updated time

            int message_data = 0;

            if (receive.Contains("66"))
            {
                //Stuff
            }
            else if (receive.Contains("61"))
            {
                //Stuff
            }
            else if (receive.Contains("55"))
            {
                //Stuff
            }
        }
    }
    catch { }
}

【问题讨论】:

  • 没有任何情况可以反复添加 DataReceived 事件处理程序。
  • connection.DataReceived += new SerialDataReceivedEventHandler(DataReceivedEvent); 关心我。您是否曾经删除过这些处理程序?
  • 也许它无关紧要,但对于 DoWork() 的每次调用,您正在向 connection.DataReceived 添加一个事件处理程序,但您并没有删除它。你也可以发布 DataReceivedEvent() 的代码吗?
  • 这可能是个问题!我不知道我为什么那样做。这会导致这种行为吗?
  • 嗯,是的,如果这条线调用您的事件,那肯定是个问题:connection.WriteLine(constant_message_section + address.ToString("X4") + command); 您将有很多人同步处理该事件。

标签: c# multithreading serial-port backgroundworker


【解决方案1】:

好的,既然没有人留下答案,我会的。问题是线

connection.DataReceived += new SerialDataReceivedEventHandler(DataReceivedEvent);

在后台工作者的计时器的每个滴答声中被调用。这将导致事件处理程序的大量实例,最终导致后台工作人员锁定并一直报告忙碌。为了纠正这个问题,我需要输入

connection.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedEvent);

为了避免有大量事件处理程序处理数据接收事件。这解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多