2016-08-21 137 views
0

这是我的情况,当我检查复选框,我的应用程序冻结,但仍然有效。这意味着它仍然能够识别通过串口发送的数据;出于测试目的,它只是退出应用程序。冷冻窗口窗体应用程序与复选框c#

如果我注释掉第45行(“pipe = arduino.ReadLine();”参见下面的截图),这意味着它不再需要“ReadLine()”,我可以取消选中该框。但是现在,当我尝试重新检查该框时,出现错误消息"Access to the port 'COM5' is denied"

我认为代码无法继续,因为它在尝试“ReadLine()”时尚未发送任何内容。但是我没有解释被拒绝访问COM端口;而不是我试图打开它已经打开的端口。

private void checkBox1_CheckedChanged(object sender, EventArgs e) 
    { 

     SerialPort arduino = new SerialPort(); 
     arduino.BaudRate = 9600; 
     arduino.PortName = comboBox1.Text; 
     string pipe; 

     if (checkBox1.Checked) 
     { 
      checkBox1.Text = "Listening..."; 
      arduino.Open(); 
       pipe = arduino.ReadLine(); 
       if (pipe == "S\r") 
       { 
        //System.Diagnostics.Process.Start("shutdown", "/f /r /t 0"); 
        System.Windows.Forms.Application.Exit(); 
       } 
     else 
     { 
      checkBox1.Text = "Start"; 
     } 
    } 
} 

回答

0

SerialPort类管理系统资源,当这样的敏感的物品都参与其中,类通常实现IDisposable接口,以允许立即释放到系统中的系统资源。

您的代码忘记关闭SerialPort,因此,下次您的用户操作导致对此事件处理程序的调用时,您的第一个操作将使用该端口。

幸运的是,以确保正确的关闭和这些对象的处置一个简单的方法,它是using statement

private void checkBox1_CheckedChanged(object sender, EventArgs e) 
{ 

    if (checkBox1.Checked) 
    { 
     checkBox1.Text = "Listening..."; 
     using(SerialPort arduino = new SerialPort()) 
     { 
      arduino.BaudRate = 9600; 
      arduino.PortName = comboBox1.Text; 
      string pipe; 
      arduino.Open(); 
      pipe = arduino.ReadLine(); 
      if (pipe == "S\r") 
      { 

       //System.Diagnostics.Process.Start("shutdown", "/f /r /t 0"); 
       //System.Windows.Forms.Application.Exit(); 
      } 
     } // Here the port will be closed and disposed. 
    } 
    else 
    { 
     checkBox1.Text = "Start"; 
    } 
} 
+0

您的解决方案的工作原理,它不再是拒绝访问端口,但它仍然冻结。我想出了为什么,问题在于“ReadLine”语句,如果没有可读的内容,它会卡住。你能帮我找到解决方案吗?我需要一个重复“ReadLine”语句的循环,但是如果找不到任何东西,那么它需要继续循环而不是卡住。 –

+0

根据MSDN:_默认情况下,ReadLine方法将阻塞,直到收到一条线。如果这种行为不受欢迎,那么将ReadTimeout属性设置为任何非零值,以强制ReadLine方法在端口上没有可用行的情况下抛出TimeoutException._当然,在那时您会捕获异常并启动另一个循环。 – Steve

+0

当我循环while(true){arduino.ReadTimeout = 500; pipe = arduino.ReadLine();}'这个程序可以工作,但是我得到一个超时错误弹出窗口。有没有办法在不被解释为错误的情况下使用'ReadTimeout',而是刷新'ReadLine'语句?我不认为我在正确的地方使用了循环。 –