private void EndReadStream(IAsyncResult callback)
        {
            int bytes = 0;

            try {
                lock (streamLock) {
                    if (stream == null || !stream.IsConnected)
                    {
                        return;
                    }

                    bytes = stream.EndRead(callback);
                }
            } catch (IOException) {
                // The pipe has been closed
                return;
            } catch (NullReferenceException) {
                return;
            } catch (ObjectDisposedException) {
                return;
            } catch {
                // Unknown error
                return;
            }

            if (bytes > 0)
            {
                using (MemoryStream memory = new MemoryStream(buffer, 0, bytes)) {
                    try {
                        PipeFrame frame = new PipeFrame();
                        if (frame.ReadStream(memory))
                        {
                            lock (frameQueue) {
                                frameQueue.Enqueue(frame);
                            }

                            FrameReceived?.Invoke();
                        }
                        else
                        {
                            Close();
                        }
                    } catch {
                        Close();
                    }
                }
            }

            if (!isClosed && IsConnected)
            {
                BeginReadStream();
            }
        }
        public bool ReadFrame(out PipeFrame frame)
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException(nameof(stream));
            }

            lock (frameQueue) {
                if (frameQueue.Count == 0)
                {
                    frame = default(PipeFrame);
                    return(false);
                }

                frame = frameQueue.Dequeue();
                return(true);
            }
        }
        public bool WriteFrame(PipeFrame frame)
        {
            if (isDisposed)
            {
                throw new ObjectDisposedException(nameof(stream));
            }

            if (isClosed || !IsConnected)
            {
                return(false);
            }

            try {
                frame.WriteStream(stream);
                return(true);
            } catch {
                // Nothing to do...
                return(false);
            }
        }