2016-11-15 5 views
0

Tcp経由で複数のデバイスと通信しています。tcpクライアントとタイマーでプログラムが固執するC#

私は3秒ごとに実行されるタイマーを持っています。

readingTimer = new System.Timers.Timer(3000); 
readingTimer.Elapsed += ReadingTimer_Elapsed; 
readingTimer.Enabled = true; 

それから私が経過した場合にデバイスのリストを反復処理し、それらの各1との接続を確立しよう:

private void ReadingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { 
     foreach (var device in Devices) 
     { 
      Console.WriteLine($"Reading device {device.number}"); 
      ReadDevice(device); 
     } 
} 

最後にReadDevice方法は、TCPクライアントを作成し、いくつかのデータを読み込もうとします:

private string ReadDevice(Device device) 
{ 
    using (TcpClient client = new TcpClient(device.Ip, device.Port)) 
    { 
     //Read Data 
     //Return Data 
    } 
} 

問題は、私は最初のデバイスだけを読んでいる、2番目のデバイスの反復は決して進入しないということです。私のリストにどれだけのデバイスがあるかは関係ありません。私はいつも "Reading device 1"を取得します。

追加情報: IPが到達できない場合、それはタイムアウトを取得するまで、プログラムは

using (TcpClient client = new TcpClient(device.Ip, device.Port)) 

でstuckedます。その後、反復は固執し、終了します。それは反復の次のデバイスに移動しません。 私は、コンストラクタは、プロセス内の同期接続を行い、それが接続されているか、失敗するまでクラスがブロックされます

catch 
{ 
    //Log error message 
    continue; 
} 
+0

時間経過メソッドでは、ビジネスロジックを呼び出す前にまずタイマーを停止して、次のタイマーティックが発生しないようにします。最後にtry catchでコードをラップして、最後にブロックしてタイマーを再起動してください。 – Hakunamatata

答えて

1

とReadingTimer_Elapsedでのtry/catchを持っています。

タイマースレッドが再びブロックされているため、事実の後に繰り返し処理が再開されている可能性があります。あなたのtry/catchブロックは接続エラー外部のを処理している必要がありますので、最初のエラーをキャッチし、デバイスループを完了することなく終了します。このため、常に最初の接続のみが表示されます。

これは私の意見で接続を処理する良い方法ではありません。あなたは衝突するようになっています。あなたがすべきことは、各接続の状態を管理し、接続エラーを処理できる別のスレッドの中でそれぞれの接続を試みることです。そうすれば、スレッドを追跡していて、スレッドが既にそれをやっているときに、あなたのタイマーが起動したときに、再度読み込みを試みることはできません。

+0

ここに非常に良い情報、私は私の変更を行います。ありがとう...もう1つの質問ですが、私は継続的なデータを期待している場合、Tcpクライアントを存続させてもよろしいですか? (その方法で私は衝突を遠ざけます) – user1416072

+0

もちろん、それはあなたがやっていることに依存するアーキテクチャ上の決定であり、それに応じて接続/伝送の他の側面を管理しなければならないかもしれません。 – JuanR

関連する問題