2016-11-29 8 views
0

特定の文字列を受け取るシリアルポート(COM)を特定しようとしています。 とにかく、私は各COMにループすると、C#はReadLineをいくつかのポート(例えばCOM 10)で接続した後にロックします。C#、一定時間後に接続しようとするシリアルを終了する

新しいThreadSerialPort.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(); 
    } 
} 

EDIT:コメントでjdwengを示唆するように私は、質問を修正します。 .Open()ではブロックされませんが、.ReadLine()ではブロックされます。

+0

これは[同じ問題](http://stackoverflow.com/q/1696238/1997232)のハックリの回避策のようです。実際の質問は、なぜ(ポートがあなたが開こうとしているか、存在しているかなど)ハングアップしていて、以前の 'Close()'に問題があるかもしれません。 Btw、 'SerialPort'の実装は本当に貧弱なことですが、多くはすでにwinapiラッパーを所有しています。 – Sinatr

+0

行の文字列temp = mysp.ReadLine();入力されるまでブロックされ、CRが見つかる。代わりにブロックしない非同期メソッドを使用します。 – jdweng

+0

ありがとう@jdweng、それは正しいです、ソフトウェアはOpenLineでロックされていませんが、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); 

も例外後finallyブロックにmysp.Close();を移動する必要があります。

0

ユーザは、どのポートを使用するか、つまり通常はどのように使用するかを設定できます。

使用可能なすべてのポートを開いて、接続を待ってから、未使用のポートを閉じます。

関連する問題