3

今回は、少なくともこの初期バージョンの MSDN の例に基づいた Async Socket Client に関連する別のネットワークに関する質問です。現在、ユーザーがインターフェイスのボタンをクリックすると、Async Connect がネットワーク デバイスに接続しようとします。コードは次のとおりです。

//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 要求のリターンを待っているためにロックしていると思いますが、これは、その接続要求を別のスレッドに置く必要があるということですか?

私が使用しているAsync Socket Clientのコードを含めました-

    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);
        }       
    }

独自のスレッドを持つ非同期クライアントを使用することで、ホストが存在しない場合にインターフェイスのフリーズが停止することを期待していましたが、そうではないようです。20 秒かかる最初の接続失敗の後、後続のすべての接続試行はすぐに返されます (1 ミリ秒未満)。また、最初の接続試行が成功した場合、存在しないホストに接続するためのその後の呼び出しがすぐに返されるという奇妙なことも考えました。何が起こっているのか少し困惑していますが、使用するソケットが AsyncSocket クラスに格納されているという事実に関連しているかどうか疑問に思っています。クライアントコードがさらに必要な場合は、私に知らせてください。

4

2 に答える 2

4

あなたはそれが非同期であると主張していますが、あなたの Connect メソッドは明らかにそうではありません:

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

完了するまでブロックします。これは、非同期動作のアンチテーゼです。BeginConnect接続されるまでブロックする場合、使用する意味は何ですか?

于 2012-04-11T09:45:06.447 に答える
1

ここで UI スレッドをブロックしています:

connectDone.WaitOne();  //Blocks until the connect operation completes, (time taken?) timeout?
于 2012-04-11T09:45:13.903 に答える