【问题标题】:C# program with COM port going NOT RESPONDING带有 COM 端口的 C# 程序没有响应
【发布时间】:2023-03-18 03:48:01
【问题描述】:

我有 C#/.NET 程序,它使用 COM 端口和带有 WCF 服务的 SQL CE 数据库。有时程序会变得无响应(窗口冻结),即使在调试模式下我也找不到原因。

我可以在重启我的电脑或 COM 端口后重启程序。问题不在于我的 COM 端口问题,因为我已经在许多 PC 上尝试过,并且都有相同的问题。

我该如何解决这个问题?

private void timer_Tick(object sender, EventArgs e)
{
    try
    {
        labeltimer.Text = DateTime.Now.ToString();
        if (timerstarted == true)
        {
            return;
        }
        timerstarted = true;
        _CARDCODE = 0;
        string error = "";
        bool hasbassed = false;
        if (this._Close == true)
        {
            this.Close();
        }

        if (serialPort1.IsOpen)
        {
            if (i < 8)
            {
                i++;
            }
            else
            {
                i = 0;
            }
            to[0] = (byte)(128 + i);
            try
            {
                serialPort1.Write(to, 0, 1);
            }
            catch (System.Exception ex)
            {
                ListViewItem Lvi = new ListViewItem((++rowcount).ToString());
                Lvi.SubItems.Add("");
                Lvi.SubItems.Add("");
                Lvi.SubItems.Add("Disconnected");
                Lvi.SubItems.Add("");
                listView.Items.Add(Lvi);
                StartPort();
            }


            if (progressBar.Value >= 1500)
                progressBar.Value = 0;
            else
                progressBar.Value += 10;

            if (serialPort1.BytesToRead != 0)
            {

                byte[] data = new byte[serialPort1.BytesToRead];
                from = new byte[3];
                try
                {
                    serialPort1.Read(data, 0, data.Length);
                }
                catch (System.Exception ex)
                {
                    ListViewItem LVi = new ListViewItem((++rowcount).ToString());
                    LVi.SubItems.Add("");
                    LVi.SubItems.Add("");
                    LVi.SubItems.Add("Disconnected");
                    LVi.SubItems.Add("");
                    listView.Items.Add(LVi);
                    StartPort();
                }
                // data.Length == 4 by Button or HassPassed
                if (data.Length == 4)
                {
                    if (data[1] > 2)
                        DBS.AddButtonPass(data[0], data[1] / 4);
                    else
                    {
                        DBS.EditPass((int)data[0]);
                        timerstarted = false;
                        return;
                    }

                }
                else if ((data[data.Length - 1] != 255) || (data.Length < 4))
                {
                    from[0] = data[0];
                    from[1] = 0;
                    from[2] = 0;
                    serialPort1.Write(from, 0, 3);
                    timerstarted = false;
                    return;
                }

                //RegistoringSubscriber_ID Add Subscriber Card
                else if ((RegistoringSubscriber_ID > 0) && (RegisterCheckpoint != 0) && (data[0] == RegisterCheckpoint))
                {
                    Registoring = false;
                    if (RegistorNewCard(Convert.ToInt32(data[2].ToString() + data[3].ToString() + data[4].ToString())) > 0)
                        FormBringPC.AnswerType = 1;
                    else
                        FormBringPC.AnswerType = 2;
                    RegistoringSubscriber_ID = 0;

                    error = "register card";
                }
                // RegistoringSubscriber_ID < 0 Add Bonus Card
                else if ((RegistoringSubscriber_ID < 0) && (RegisterCheckpoint != 0) && (data[0] == RegisterCheckpoint))
                {
                    Registoring = false;
                    if (RegistorBonusCard(Convert.ToInt32(data[2].ToString() + data[3].ToString() + data[4].ToString())) > 0)
                        FormBringPC.AnswerType = 1;
                    else
                        FormBringPC.AnswerType = 2;
                    RegistoringSubscriber_ID = 0;

                    error = "register Bonus card";
                }
                else if ((List_Checkpoint_ID.Contains(data[0]) && ((data[1] == 130) || (data[1] == 129))))
                {
                   //     DBS.EditPass((int)data[0]);
                }
                else if ((List_Checkpoint_ID.Contains(data[0]) && (data.Length == 7)))
                {
                    _CARDCODE = Convert.ToInt32(data[2].ToString() + data[3].ToString() + data[4].ToString());
                    GlobalTypes.InvalidPass pass = DBS.CheckPassStatus(_CARDCODE, (int)data[0], (int)data[1]);
                    if (pass == GlobalTypes.InvalidPass.Valid)
                    {
                        from[0] = data[0];
                        from[1] = 1;
                        from[2] = 1;
                        serialPort1.Write(from, 0, 3);
                        LBTitle.Text = DateTime.Now.ToLongTimeString();
                        hasbassed = true;
                    }
                    else
                    {
                        from[0] = data[0];
                        from[1] = 0;
                        from[2] = 0;
                        serialPort1.Write(from, 0, 3);
                        switch (pass)
                        {
                            case GlobalTypes.InvalidPass.InvalidCard:
                                {
                                    error = "Չգրանցված քարտ";
                                    break;
                                }
                            case GlobalTypes.InvalidPass.InvalidCount:
                                {
                                    error = "Այց. քանակ";
                                    break;
                                }
                            case GlobalTypes.InvalidPass.InvalidGraphic:
                                {
                                    error = "Ժամանակ hh:mm:ss";
                                    break;
                                }
                            case GlobalTypes.InvalidPass.InvalidPeriod:
                                {
                                    error = "Ժամանակահատված xxxx.dd.yyy";
                                    break;
                                }
                            case GlobalTypes.InvalidPass.InvalidStatus:
                                {
                                    error = "Հառացված աբոնենտ";
                                    break;
                                }
                            case GlobalTypes.InvalidPass.InvalidSuscribe:
                                {
                                    error = "Անհայտ բաժանորդ";
                                    break;
                                }
                            default:
                                {
                                    error = "esim inch";
                                    break;
                                }
                        }
                    }
                }
                else if ((List_Checkpoint_ID.Contains(data[0]) && (data.Length > 0)))
                {
                    try
                    {
                        byte[] ticket = new byte[data.Length - 6];

                        for (int ii = 0; ii < data.Length - 6; ii++)
                        {
                            ticket[ii] = data[ii + 2];
                        }

                        _CARDCODE = Convert.ToInt32(Encoding.ASCII.GetString(ticket.ToArray()));
                        GlobalTypes.HasPass pass = DBS.CheckTicketPassStatus(_CARDCODE, (int)data[0], (int)data[1]);
                        if (pass == GlobalTypes.HasPass.TruePass)
                        {
                            from[0] = data[0];
                            from[1] = 1;
                            from[2] = 1;
                            serialPort1.Write(from, 0, 3);
                            LBTitle.Text = DateTime.Now.ToLongTimeString();
                            hasbassed = true;
                        }
                        else
                        {
                            from[0] = data[0];
                            from[1] = 0;
                            from[2] = 0;
                            serialPort1.Write(from, 0, 3);
                            switch (pass)
                            {
                                case GlobalTypes.HasPass.CardNotFound:
                                    {
                                        error = "Not registored ticket";
                                        break;
                                    }
                                case GlobalTypes.HasPass.CardRepeat:
                                    {
                                        error = "ReEntring";
                                        break;
                                    }
                                case GlobalTypes.HasPass.ValidationPeriodError:
                                    {
                                        error = "Ժամանակ hh:mm:ss";
                                        break;
                                    }
                                case GlobalTypes.HasPass.SeasonError:
                                    {
                                        error = "Ժամանակահատված xxxx.dd.yyy";
                                        break;
                                    }
                                case GlobalTypes.HasPass.WeekOfDayError:
                                    {
                                        error = "Day of Weak";
                                        break;
                                    }
                                default:
                                    {
                                        error = "esim inch";
                                        break;
                                    }
                            }
                        }
                    }
                    catch { timerstarted = false; return; }
                }
                if (rowcount >= 10)
                {
                    rowcount = 0;
                    listView.Items.Clear();
                }
                ListViewItem lvi = new ListViewItem((++rowcount).ToString());
                lvi.SubItems.Add(data[0].ToString());
                if (data.Length == 4)
                    hasbassed = true;
                if (((data[1] == 2) || (data[1] == 8)) && ((data.Length == 4) || (Dictionary_Chekpoint[data[0]].CheckPointType == 2)))
                {
                    lvi.SubItems.Add("Ելք");
                }
                else
                {
                    lvi.SubItems.Add("Մուտք");
                }
                if (data.Length != 4)
                    lvi.SubItems.Add(_CARDCODE.ToString());
                else
                    lvi.SubItems.Add("Հերթապահ");
                lvi.SubItems.Add(error);
                if (hasbassed == true)
                {
                    lvi.BackColor = Color.LightGreen;
                }
                else
                {
                    lvi.BackColor = Color.LightPink;
                }
                listView.Items.Add(lvi);
            }
        }
        else MessageBox.Show("Serial port is closed!", "RS232 tester", MessageBoxButtons.OK, MessageBoxIcon.Error);
        timerstarted = false;
    }
    catch
    {
        timerstarted = false;
        return;
    }

}

【问题讨论】:

  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。见:How to create a Minimal, Complete, and Verifiable example.
  • 对吗???这是我重复的代码
  • 即使您无法隔离问题的位置,您至少可以在串行端口调用周围添加一些日志,以找出哪个阻塞了您的应用程序主线程。这将允许您提供一小段代码来说明您的问题,而不是倾倒您的整个代码以期望我们完成您的工作。我也非常确信 Justin 是对的,并且您正在 GUI 线程中进行串行端口阻塞调用。

标签: c# sql .net wcf serial-port


【解决方案1】:

只要主 UI 线程中发生阻止 UI 处理的处理,C# 程序就会显示为 NOT RESPONDING。这里的一般答案是将工作推送到不同的线程中,以便 UI 事件可以继续处理(有关更多信息,请参阅下面的参考资料)。在串口的情况下,最简单的做法是挂钩 SerialPort.DataReceived 事件而不是轮询它:https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived%28v=vs.110%29.aspx

参考:

GUI not responding while fetching data

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/dd744765%28v=vs.85%29.aspx

http://www.dreamincode.net/forums/topic/246911-c%23-multi-threading-in-a-gui-environment/

【讨论】:

  • 这对我没有帮助,因为,我的 UI 并不重要,重要的是程序,它回答 DB 上的 COM 端口读/写,如果 UI 工作但我的第二个线程没有响应,那对我没有帮助,我需要解决问题,
  • 如果 UI 不重要,那么您应该考虑将代码重写为服务而不是 winforms 应用程序。
  • 在我的 winform 中,我在线显示 shchedule 并且它运行得更快,如果我从表单创建服务而不是我的查询会变慢,
  • 很难从您给我们的内容中确定,但您似乎在一个线程(UI 线程)中做所有事情。因此,任何一件事情花费很长时间都会导致其余的事情被延迟。为了获得最佳性能,您需要将 UI、串行端口和数据库访问分离到不同的线程中,或者至少将它们切换到事件,这样它们就不会被阻塞。从 WinForms 切换到服务并不能解决根本问题,它只是改变了事情;我建议它只是因为你说 UI 不重要(听起来 UI 实际上很重要)。
  • 我在 UI 中显示的内容并不是很重要,程序继续工作很重要...感谢线程,我认为这将有助于我今天尝试
猜你喜欢
  • 2011-06-24
  • 2017-10-06
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 2011-01-10
  • 1970-01-01
相关资源
最近更新 更多