//returns true if receive completed synchronously, false otherwise
        bool StartAsyncReceive(UdpSocket socket)
        {
            Fx.Assert(socket != null, "UdpSocketReceiveManager.StartAsyncReceive: Socket should never be null");                         
            bool completedSync = false;

            ArraySegment<byte> messageBytes = default(ArraySegment<byte>);
            UdpSocketReceiveState state = null;

            lock (this.thisLock)
            {
                if (!this.IsDisposed && socket.PendingReceiveCount < this.maxPendingReceivesPerSocket)
                {
                    IAsyncResult result = null;
                    byte[] receiveBuffer = this.receiveBufferPool.Take();
                    try
                    {
                        state = new UdpSocketReceiveState(socket, receiveBuffer);
                        EndPoint remoteEndpoint = socket.CreateIPAnyEndPoint();

                        result = socket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, ref remoteEndpoint, onReceiveFrom, state);
                    }
                    catch (Exception e)
                    {
                        if (!Fx.IsFatal(e))
                        {
                            this.receiveBufferPool.Return(receiveBuffer);
                        }
                        throw;
                    }

                    if (result.CompletedSynchronously)
                    {
                        completedSync = true;
                        messageBytes = EndReceiveFrom(result, state);
                    }
                }
            }

            if (completedSync)
            {
                messageBytes = this.CopyMessageIntoBufferManager(messageBytes);
                //if HandleDataReceived returns false, it means that the max pending message count was hit.
                //when receiveHandler.HandleDataReceived is called (whether now or later), it will return the buffer to the buffer manager.
                return this.receiveHandler.HandleDataReceived(messageBytes, state.RemoteEndPoint, state.Socket.InterfaceIndex, this.onMessageDequeued);
            }

            return false;
        }