2016-11-29 62 views
0

我试图找出一个接收某个字符串的串口(COM)。 无论如何,如果我在每个COM上循环,则C#在某些端口(例如COM 10)上连接后锁定ReadLine。C#,杀死一段时间后试图连接的串口

我想在新的Thread上启动SerialPort.ReadLine(),经过一段时间后我终止了这个线程。 无论如何,我正在考虑是否有更“优雅”的方式来达到同样的效果。

这里张贴的代码的一部分:

String com=""; 
for (int i= 0; i< ports.Length; i++) //ports is an array of String, the elements are the opened COM 
{ 
    mysp= new SerialPort(ports[i], 9600); 
    try { 
     mysp.Open(); 
     String temp = mysp.ReadLine(); //HERE INFINITE LOOP ON CERTAIN PORTS 
     if (temp.IndexOf("*") > -1) 
     { 
      com = ports[i]; //Set the correct COM port 
      i = ports.Length; 
      mysp.Close(); 
     } 
    }catch(Exception e) 
    { 
     Console.WriteLine("Exception "+e+" on " + ports[i]); 
     mysp.Close(); 
    } 
} 

编辑:我纠正问题,如建议在评论jdweng。它不会在.Open()上阻止,但会在.ReadLine()上阻止。

+0

这对于[同样的问题](http://stackoverflow.com/q/1696238/1997232)看起来像一个hacky解决方法。真正的问题是它为什么会挂起(你想打开哪个端口,是否存在等),也许你以前的'Close()'有问题。顺便说一下,'SerialPort'的实现是非常糟糕的事情,许多已经转换到自己的winapi包装。 – Sinatr

+0

该行String temp = mysp.ReadLine();直到在输入中找到CR为止。而是使用不阻塞的异步方法。 – jdweng

+0

谢谢@jdweng,这是正确的,软件不锁定打开,但在ReadLine上。现在我试着看看异步方法如何在C#上工作。 – youngz

回答

0

您可以用指定的超时将呼叫打包在Task中。

int timeout = 5000; // Cancel the task after 5 seconds 
Task.Run(() => { 
    var temp = mysp.ReadLine(); //HERE INFINITE LOOP ON CERTAIN PORTS 
    if (temp.IndexOf("*") > -1) 
    { 
     com = ports[i]; //Set the correct COM port 
     i = ports.Length; 
     mysp.Close(); 
    } 
}).Wait(timeout); 

也应该移动到mysp.Close();异常后finally块。

0

您可以让用户配置使用哪个端口,这是通常的做法。或者打开所有可用的端口,等待您的连接,然后关闭未使用的端口。