C#异步套接字客户端阻止主界面线程

时间:2012-04-11 09:42:27

标签: c# sockets networking asynchronous timeout

此次的另一个网络问题与Async套接字客户端有关,该客户端至少基于MSDN示例的初始版本。目前,当用户单击界面上的按钮时,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...
}

如果终点已打开且存在于网络上,则此代码可正常工作(整个操作不到一秒钟)。但是,如果联网设备被关闭或不可用,则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);
        }       
    }

我希望通过使用具有自己的线程的Async客户端,如果主机不存在,这将会停止冻结接口,但事实并非如此。在初始连接失败(需要20秒)之后,立即返回所有后续连接尝试(小于1毫秒)。还有一些我觉得奇怪的事情,如果初始连接尝试成功,任何后来连接到不存在的主机的调用都会立即返回。有点困惑的是发生了什么,但想知道它是否与我使用的Socket存储在我的AsyncSocket类中的事实有关。任何帮助非常感谢,如果需要更多的客户端代码,请告诉我。

2 个答案:

答案 0 :(得分:4)

您声称它是异步的,但您的Connect方法显然不是:

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

你阻塞直到它完成,这是异步行为的对立面。使用BeginConnect时,如果你要阻止它直到它被连接,有什么意义呢?

答案 1 :(得分:1)

你在这里阻止你的UI线程:

connectDone.WaitOne();  //Blocks until the connect operation completes, (time taken?) timeout?