日期:2014-05-17  浏览次数:20938 次

SocketAsyncEventArgs 疑问
hello everyone
我现在学SocketAsyncEventArgs类,下载微软的示例代码看,有个地方不懂,希望大家能指导一下:
C# code
public void StartAccept(SocketAsyncEventArgs acceptEventArg)
        {
            if (acceptEventArg == null)
            {
                acceptEventArg = new SocketAsyncEventArgs();
                acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
            }
            else
            {
                acceptEventArg.AcceptSocket = null;//清空连接socket
            }

            m_maxNumperOfAcceptedClients.WaitOne();//使用连接上限
            bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);//开始接入连接
            if (!willRaiseEvent)
            {
                ProcessAccept(acceptEventArg);
            }
        }
           

bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);这一句按msdn的介绍是开始异步接收连接。如果i/o挂起,将返回true,操作完成时,将引发 e 参数的 SocketAsyncEventArgs .Completed 事件。 如果 I/O 操作同步完成,将返回 false。 将不会引发 e 参数的 SocketAsyncEventArgs .Completed 事件,并且可能在方法调用返回后立即检查作为参数传递的 e 对象以检索操作的结果。 但是这个示例上的代码好像都会引发SocketAsyncEventArgs .Completed 事件。这样写有什么用呢?
谢谢

------解决方案--------------------
怎么会呢,只有 willRaiseEvent 为true,才会会引发
------解决方案--------------------
探讨
还有个问题:
const int opsToPreAlloc = 2; // read, write (don't alloc buffer space for accepts)
为什么申请2倍的缓冲。

------解决方案--------------------
微软的解释:
如果 I/O 操作同步完成,将返回 false。 将不会引发 e 参数的 SocketAsyncEventArgs.Completed 事件,并且可能在方法调用返回后立即检查作为参数传递的e 对象以检索操作的结果。 

但事实却并非如此,微软经常喜好把东西设计的非常强大,看似强大,而实际却做不到,这里就是这种情况。微软的初衷正如MSDN上面解释的那样,示例代码也是根据MSDN的解释来写的,但反编译dll会发现,其实那个方法根本就是偷工减料的方法,它只会在失败的场合同步完成,返回false,成功的场合都是异步完成的。
总结下就是:同步完成的情况下,其处理结果肯定是失败;而异步完成的情况下,处理结果可能为成功,也可能为失败。