2012-04-11 27 views
3

この初期のバージョンでは、MSDNの例に基づくAsync Socket Clientに関連するもう1つのネットワーキングに関する質問です。ユーザがインターフェース上のボタンをクリックしたときに非同期接続の試行がネットワークデバイスに接続するように構成されている現在、コードが以下に示される -C#Asyncソケットクライアントブロックメインインターフェイススレッド

//Mouse Event handler for main thread 
private void btn_Read_MouseDown(object sender, MouseEventArgs e) 
{ 
    Stopwatch sw = Stopwatch.StartNew(); 
    if (!networkDev.Connected) 
     networkDev.Connect("192.168.1.176", 1025); 

    if(networkDev.Connected) 
     networkDev.getReading(); 
    sw.Stop();//Time time taken... 
} 

エンドポイントがオンし、ネットワーク上でこのコードは存在している場合うまく動作します(全体的な操作では1秒未満です)。ただし、ネットワーク接続されたデバイスの電源を切るか、使用できない場合は、AsyncSocket Connect関数がメインフォームスレッドを保持します。現在、デバイスが使用できない場合は、インターフェイス全体が約20秒間ロックされます(ストップウォッチを使用)。私はメインスレッドがConnectリクエストのリターンを待っているのでロックしていると思います。これは別のスレッドに接続要求を入れる必要があるのですか?

私は、コード、私が使用しています非同期ソケットクライアントが含まれている -

public bool Connect(String ip_address, UInt16 port) 
    { 
     bool success = false; 

     try 
     { 
      IPAddress ip; 
      success = IPAddress.TryParse(ip_address, out ip); 
      if (success) 
       success = Connect(ip, port); 
     } 
     catch (Exception ex) 
     { 
      Console.Out.WriteLine(ex.Message); 
     } 
     return success; 
    }  

    public bool Connect(IPAddress ip_address, UInt16 port) 
    { 
     mSocket.BeginConnect(ip_address, port, 
      new AsyncCallback(ConnectCallback), mSocket); 
     connectDone.WaitOne();//Blocks until the connect operation completes, 
           //(time taken?) timeout? 
     return mSocket.Connected; 
    } 

    private void ConnectCallback(IAsyncResult ar) 
    { 
     //Retreive the socket from thestate object 
     try 
     { 
      Socket mSocket = (Socket)ar.AsyncState; 
      //Set signal for Connect done so that thread will come out of 
      //WaitOne state and continue 
      connectDone.Set(); 

     } 
     catch (Exception ex) 
     { 
      Console.Out.WriteLine(ex.Message); 
     }  
    } 

私はそれ自身のスレッドを持つ非同期クライアントを使用して、これは、ホストのdidn場合インタフェースを凍結停止することをことを期待していたがこれは存在しないと思われる。 20秒かかる最初の接続障害の後、すべての後続の接続試行がすぐに返されます(1ミリ秒未満)。また、私が奇妙に思ったことは、初期接続の試行が成功すると、それ以降の呼び出しが存在しないホストに接続すると直ちに戻ります。何が起こっているのか少し困惑していますが、私が使用するソケットがAsyncSocketクラスに格納されているかどうかは疑問です。クライアントコードの多くが必要な場合は、私に教えてください、どんな助けも大いに感謝します。

+0

どこそれが言うWAITONEする次のコメントでは、「ブロック操作が完了するまで」?それはどのくらい正確に非同期で、どのスレッドがブロックすると思いますか。 – R0MANARMY

+0

凍結しているインターフェースの問題点を明白に知っているので、これを今取り上げました。これは最初の質問だったインターフェイスの問題を解決しますが、Connectが完了できない場合、私はそのソケットを再び使用できません。比較的頻繁に切断が発生すると、これが問題になります。各AsyncClientは1ソケットに縛られていますが、再接続を許可する最も良い方法は何ですか?現在のところ、スレッドが以前の開始接続を待っているという例外を得るだけです。より良い解決策に関する提案は高く評価されます。 – jackocurly0074

答えて

4

は、あなたはそれが非同期の主張が、あなたのConnectメソッドは、明らかではありません:作業が完了されるまであなたが非同期動作のアンチテーゼである、ブロックしている

mSocket.BeginConnect(ip_address, port, ...); 
connectDone.WaitOne(); // Blocks until the connect operation completes [...] 

。接続するまでブロックする場合、BeginConnectを使用するポイントは何ですか?

+0

Hmm MSDNの例を使って自分のコードをベースにしているので、WaitOneを接続する理由を理解できません。私は、このサンプル(http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx)が適切な出発点となることを期待していました。私は間違っていたようだ!私がボタンを数回押すと待たずに、別の操作が進行している間に接続できないという多くの例外が出ます。とにかく他の接続の試行をタイムアウトさせるのが速いので、不安定な環境では再接続を頻繁に行うことができますか? – jackocurly0074

+1

@ jackocurly0074:接続タイムアウトのプロパティは表示できませんが、複数の同時接続を試みないように注意してください。 –

1

あなたはここにあなたのUIスレッドをブロックしている:

あなたが見
connectDone.WaitOne(); //Blocks until the connect operation completes, (time taken?) timeout? 
+0

皆さん、とても速く返信してくれてありがとうございます! WaitOneを実行すると、インターフェイスは停止しますが、別の問題が発生します。 - System.dllで 'System.InvalidOperationException'タイプの最初のチャンス例外が発生しました 同じソケットで別の非同期操作が進行中の場合、BeginConnectを呼び出すことはできません。 問題は、ソケットが接続に失敗すると再び使用できなくなり、問題のランタイムの残りの部分では使用できないように見えることです。 – jackocurly0074