private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state)
        {
            CheckConnectOperationsServerWithHandle();

            if (!IsAsync)
            {
                throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
            }

            // Create and store async stream class library specific data in the
            // async result
            PipeAsyncResult asyncResult = new PipeAsyncResult();

            asyncResult._threadPoolBinding = _threadPoolBinding;
            asyncResult._userCallback      = callback;
            asyncResult._userStateObject   = state;

            IOCancellationHelper cancellationHelper = state as IOCancellationHelper;

            // Create wait handle and store in async result
            ManualResetEvent waitHandle = new ManualResetEvent(false);

            asyncResult._waitHandle = waitHandle;

            NativeOverlapped *intOverlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
            {
                // Unpack overlapped, free the pinned overlapped, and complete the operation
                PipeAsyncResult ar = (PipeAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
                Debug.Assert(ar._overlapped == pOverlapped);
                ar._threadPoolBinding.FreeNativeOverlapped(pOverlapped);
                ar._overlapped = null;
                AsyncWaitForConnectionCallback(errorCode, numBytes, ar);
            }, asyncResult, null);

            asyncResult._overlapped = intOverlapped;

            if (!Interop.mincore.ConnectNamedPipe(InternalHandle, intOverlapped))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode == Interop.mincore.Errors.ERROR_IO_PENDING)
                {
                    if (cancellationHelper != null)
                    {
                        cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
                    }
                    return(asyncResult);
                }

                // WaitForConnectionCallback will not be called because we completed synchronously.
                // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
                _threadPoolBinding.FreeNativeOverlapped(intOverlapped);
                asyncResult._overlapped = null;

                // Did the client already connect to us?
                if (errorCode == Interop.mincore.Errors.ERROR_PIPE_CONNECTED)
                {
                    if (State == PipeState.Connected)
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected);
                    }
                    asyncResult.CallUserCallback();
                    return(asyncResult);
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }
            // will set state to Connected when EndWait is called
            if (cancellationHelper != null)
            {
                cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
            }

            return(asyncResult);
        }
        private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Object state)
        {
            CheckConnectOperationsServerWithHandle();

            if (!IsAsync)
            {
                throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
            }

            // Create and store async stream class library specific data in the
            // async result
            PipeAsyncResult asyncResult = new PipeAsyncResult();

            asyncResult._handle          = InternalHandle;
            asyncResult._userCallback    = callback;
            asyncResult._userStateObject = state;

            IOCancellationHelper cancellationHelper = state as IOCancellationHelper;

            // Create wait handle and store in async result
            ManualResetEvent waitHandle = new ManualResetEvent(false);

            asyncResult._waitHandle = waitHandle;

            // Create a managed overlapped class
            // We will set the file offsets later
            Overlapped overlapped = new Overlapped();

            overlapped.OffsetLow   = 0;
            overlapped.OffsetHigh  = 0;
            overlapped.AsyncResult = asyncResult;

            // Pack the Overlapped class, and store it in the async result
            NativeOverlapped *intOverlapped = overlapped.Pack(s_WaitForConnectionCallback, null);

            asyncResult._overlapped = intOverlapped;
            if (!Interop.mincore.ConnectNamedPipe(InternalHandle, intOverlapped))
            {
                int errorCode = Marshal.GetLastWin32Error();

                if (errorCode == Interop.ERROR_IO_PENDING)
                {
                    if (cancellationHelper != null)
                    {
                        cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
                    }
                    return(asyncResult);
                }

                // WaitForConnectionCallback will not be called because we completed synchronously.
                // Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
                Overlapped.Free(intOverlapped);
                asyncResult._overlapped = null;

                // Did the client already connect to us?
                if (errorCode == Interop.ERROR_PIPE_CONNECTED)
                {
                    if (State == PipeState.Connected)
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected);
                    }
                    asyncResult.CallUserCallback();
                    return(asyncResult);
                }

                throw Win32Marshal.GetExceptionForWin32Error(errorCode);
            }
            // will set state to Connected when EndWait is called
            if (cancellationHelper != null)
            {
                cancellationHelper.AllowCancellation(InternalHandle, intOverlapped);
            }

            return(asyncResult);
        }