我在弄Socket相关的程序
如果慢慢的点按钮来执行,,一般不会出现问题但是,如果快速点按钮,,就出错了一出错就直接停止调试,,连个错误提示都没有,都不知道在哪里有问题怎么解决?我的Socket都是用Async来操作的

解决方案 »

  1.   

    没有用到线程,,只是Socket用的都是ReceiveAsync和SendAsync
      

  2.   


    原来如此。。我现在已经知道哪里出错了我在SocketAsyncEventArgs的Completed事件中
    处理信息,然后引发我的事件但是,这个时候还没有开始ReceiveAsync,所以出错现在我引发事件就是用新线程,就能解决问题了。。
    TCPListenerClient client = clients.SingleOrDefault(c => c.socket == e.AcceptSocket);
    if (client == null)
        return;
    if (e.BytesTransferred == 0)
    {
        e.AcceptSocket.Close();
        clients.Remove(client);
        if (DisconnectCompleted != null)
        {
            System.Threading.Thread t = new System.Threading.Thread(() =>
                {
                    DisconnectCompleted(client, e);
                });
            t.Start();
        }
        return;
    }if (ReceiveCompleted != null)
    {
        System.Threading.Thread t = new System.Threading.Thread(() =>
            {
                ReceiveCompleted(client, e);
            });
        t.Start();
    }SocketAsyncEventArgs s = new SocketAsyncEventArgs();
    s.AcceptSocket = client.socket;
    s.Completed += Received;
    s.SetBuffer(new byte[ReceiveBufferSize], 0, ReceiveBufferSize);
    client.socket.ReceiveAsync(s);我在每个Received里,都创建一个新SocketAsyncEventArgs来接收下一条数据
    这样原来的SocketAsyncEventArgs在事件使用完后,会不会释放?
      

  3.   

    你这种接收一次消息就创建一次新线程的办法不是很好啊应该用ManualResetEvent或者autoresetevent,来waitone,然后在你所有的事件处理完,在处理函数最后写上set(),这样就可以了,
    还有如果你想无限接收数据,那就用递归调用接收函数的方法体。反正你这种用法我没用过我一般都用beginReceive的方式,然后在回眺函数里无限递归,
      

  4.   

    我说的就是这个意思,你引发事件,难道你收一条信息就创建一次新线程,然后事件完了就关闭,确实可以避免与主线程冲突的问题,但是你不觉得创建线程再销毁,很麻烦吗象我一样beginreceive开始接收数据,然后在回调函数里写上endreceive,然后这个函数里最后都要再调用这个回调函数本身,这比你创建那么多线程好的多。你只所以要用新线程来引发事件,恐怕你事件是同步的,事件不执行完就不会继续做别的事。除非你的事件处理函数里是那种大量消耗时间的操作,不然别这么干
      

  5.   

    那我用Async的怎么处理这个问题?不用线程,事件不处理完就不会继续接收。我这Socket部分是做成一个类库的,供其他程序调用。
      

  6.   


    先执行ReceiveAsync,然后才触发事件。把你的什么线程删掉!
      

  7.   

    我自己做的也是做成类库,供外部调用的。async也是异步,那就肯定有一个开始解收和结束接收,我想应该是你说的complete方法了。ManualResetEvent这个你查查msdn,还有相关的一些东西,这个是专门控制线程堵塞的,他不同于join啥的,他就是waitone就等待。然后在你complete函数内,处理完你的业务了你就set回去,就可以了,能够达到你要的不执行完就不继续接收数据
      

  8.   


    用这个解决不了吧。。目的是要分开Receive与引发事件的线程。。
    现在把引发事件放在Async后,目的就达到了
      

  9.   

    其实你自己的说的很明白,你自己脑筋一下子糊涂了。看看你说了什么,你又说事件处理中需要放在ReceiveAsync之后才执行(也就是说你知道事件不仅仅要等到connect,而且要等待准备好监听之后才回调通知),可是代码又硬要把ReceiveAsync放在触发事件的后边。很多时候我们把大白话说顺溜了,这就是一种设计。这需要你能够把自己放在对立面,好好看看自己的逻辑。