2016-11-29 63 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

您可以讓用戶配置使用哪個端口,這是通常的做法。或者打開所有可用的端口,等待您的連接,然後關閉未使用的端口。