利用Socket异步连接远程,发出异步连接请求后,在连不上的情况下,等待的时间比较长,WinForm卡在那里不动了,我这样改代码正确吗?该如何写呢?代码如下:                _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(_ip), _port);
                _client.Ttl = 10;//这句有效吗?
                _client.BeginConnect(ipep, new AsyncCallback(ConnectCallback), _client);
                _connectDone.WaitOne(100, true);//第二个参数该用false还是用true
                //连接成功后,异步发送数据
                ......
谢谢指点!

解决方案 »

  1.   

    C# 
    public virtual bool WaitOne (
    int millisecondsTimeout,
    bool exitContext
    )参数
    millisecondsTimeout
    等待的毫秒数,或为 Timeout.Infinite (-1),表示无限期等待。 exitContext
    为 true,则等待之前先退出上下文的同步域(如果在同步上下文中),然后在稍后重新获取它;否则为 false。  这个参数不理解,能具体说一下吗?返回值
    如果当前实例收到信号,则为 true;否则为 false。
      

  2.   

    这根本不是真正的异步编程,因为你使用了信号量阻塞机制,用异步编程的语句可是干了同步操作的事情。如果要异步编程,就不要搞什么 WaitOne,那就没有这种问题了。
      

  3.   

    http://msdn.microsoft.com/zh-cn/library/kzy257t0.aspx只有从非默认托管上下文内部调用 WaitOne 方法,exitContext 参数才有效。如果线程位于从 ContextBoundObject 派生的类实例的调用内部,则可能会发生这种情况。即使当前正在执行不是从 ContextBoundObject 派生的类(如 String)中的一个方法,只要 ContextBoundObject 位于当前应用程序域中的堆栈上,就可以在非默认上下文中执行。 当在非默认上下文中执行代码时,为 exitContext 指定 true 会导致线程在执行 WaitOne 方法之前退出该非默认托管上下文(即转换为默认上下文)。对 WaitOne 方法的调用完成之后,该线程返回到原始的非默认上下文。 这在上下文绑定类具有 SynchronizationAttribute 时会很有用。在这种情况下,将自动对类成员的所有调用进行同步,同步范围是类的整个代码部分。如果成员调用堆栈中的代码调用 WaitOne 方法并将 exitContext 指定为 true,则线程将退出同步域,这样,在调用该对象的任何成员时被阻止的线程便可以继续运行。当 WaitOne 方法返回时,执行调用的线程必须等待重新进入同步域。
    用false就好了
      

  4.   

               Socket   _client;
               _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
               _client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
               IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(_ip), _port);
               _client.Ttl = 10;//这句有效吗?
               IAsyncResult ias= _client.BeginConnect(ipep, new AsyncCallback(ConnectCallback), _client);
                int i = System.Environment.TickCount;
                //timeout 1000ms
                int timeout=1000;
                while (System.Environment.TickCount - i <= timeout)
                {
                    if (_client.Connected == true)
                    {
                        MessageBox.Show("connected success!");
                        break;
                    }
                    Application.DoEvents();
                }            if (_client.Connected == false)
                {
                    ias.AsyncWaitHandle.WaitOne(0, false);
                    MessageBox.Show("connected timeout");
                }你那个程式在运行时在连接的过程中界面仍然会没响应的。
      

  5.   


    那你何必写什么 BeginConnect 呢,同步Connect不就行了?画蛇添足了。
      

  6.   

    其实你的理由很牵强。其实我们像迅雷那样同时启动20个异步传输操作(而更多地则等待之前有传输结束了才开始),或者假设我们在定时器的帮助下每1秒钟给下一个的“远程”传送数据,那也都是异步的观念。不论怎么写,都用不到你所写的 WaitOne。关键是你从msdn的烂“范例”上看到这这个东西,随便抄来就用了。如果不抄袭它,自己设计呢?