2012-04-11 96 views
3

这次的另一个网络问题涉及基于MSDN示例的异步套接字客户端,至少在此初始版本中。目前,当用户点击一个异步连接尝试连接到网络设备的接口上的按钮,该代码如下所示 -C#异步套接字客户端块主接口线程

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

我希望通过它有自己的线程中的异步客户端,这将然后停止冻结如果主机没界面不存在,但似乎并非如此。初始连接失败后需要20秒,所有后续连接尝试立即返回(小于一个毫秒)。还有一件我觉得奇怪的事情,如果初始连接尝试成功,任何稍后调用连接到一个不存在的主机立即返回。对发生了什么感到困惑,但是想知道它是否与我使用的Socket存储在我的AsyncSocket类中有关。任何帮助非常感谢,如果更多的客户端代码需要让我知道。

+0

你看到在旁边WaitOne的评论,它说“阻塞,直到操作完成”?这个异步程序到底是什么,你认为它阻塞了哪个线程。 – R0MANARMY 2012-04-11 09:53:16

+0

我现在把这件事看出来了,因为事后看来,这种冻结界面的问题非常明显。这解决了接口问题,这是最初的问题,尽管看起来如果Connect无法完成,我不能再次使用该套接字,并且这在连接可能相对频繁地发生时是个问题。每个AsyncClient绑定到1个套接字,最好的方式是什么允许重新连接?目前我只是收到异常,表示线程正在等待先前的开始连接。有关更好的解决方案的任何建议,我们感激。 – jackocurly0074 2012-04-11 10:22:18

回答

4

你声称它是异步的,但你的连接方法显然不是:

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

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

+0

嗯我使用MSDN示例来基于我的代码,所以我不明白他们为什么把一个WaitOne到连接?我希望这个例子(http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx)是一个不错的起点。似乎我错了!没有等待,如果我按下按钮几次,它会提出很多例外,说明另一个操作正在进行时无法连接。无论如何要更快地暂停其他连接尝试,以便在不稳定的环境中可以更频繁地进行重新连接尝试? – jackocurly0074 2012-04-11 09:55:29

+1

@ jackocurly0074:我看不到任何连接超时属性,但是你应该确保你不尝试创建多个并发连接。 – 2012-04-11 10:02:51

1

你在这里挡住你的UI线程:

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

你们回复得非常快,谢谢!取出WaitOne会阻止界面冻结,但会产生另一个问题。这发生在随后的连接尝试 - > System.dll中发生类型'System.InvalidOperationException'的第一次机会异常 在同一套接口上正在进行另一个异步操作时,无法调用BeginConnect。 问题是,一旦套接字连接失败,我不能再次使用它,它似乎是其他运行有问题的不可用的? – jackocurly0074 2012-04-11 10:03:24