protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         _lock.AcquireWriterLock();
         try
         {
             {
                 while (_outgoingQueue.Count > 0)
                 {
                     RtmpAsyncResult asyncResult = _outgoingQueue.Dequeue() as RtmpAsyncResult;
                     if (asyncResult != null)
                     {
                         asyncResult.SetComplete(new ObjectDisposedException(null));
                     }
                 }
                 _outgoingQueue.Clear();
             }
         }
         finally
         {
             _lock.ReleaseWriterLock();
         }
     }
     base.Dispose(disposing);
 }
        public override void EndWrite(IAsyncResult asyncResult)
        {
            RtmpAsyncResult result = asyncResult as RtmpAsyncResult;

            try
            {
                if (!asyncResult.IsCompleted)
                {
                    asyncResult.AsyncWaitHandle.WaitOne();

                    /*
                     * if (!asyncResult.AsyncWaitHandle.WaitOne(milliseconds, false))
                     * {
                     *  throw new TimeoutException();
                     * }
                     */
                }
                if (result.HasException())
                {
                    throw result.Exception;
                }
            }
            finally
            {
                TryBeginWrite();
            }
        }
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            RtmpAsyncResult item = new RtmpAsyncResult(callback, state, buffer, offset, count);

            lock (this._outgoingQueue)
            {
                this._outgoingQueue.Enqueue(item);
            }
            this.TryBeginWrite();
            return(item);
        }
        private void TryBeginWrite()
        {
            RtmpAsyncResult asyncResult = null;

            _lock.AcquireWriterLock();
            try
            {
                if (this.IsWriting)
                {
                    return;
                }
                if (_outgoingQueue.Count > 0)
                {
                    asyncResult = _outgoingQueue.Dequeue() as RtmpAsyncResult;
                    SetIsWriting(true);
                }
            }
            finally
            {
                _lock.ReleaseWriterLock();
            }
            try
            {
                if (asyncResult != null)
                {
                    this.InternalBeginWrite(asyncResult.Buffer, asyncResult.Offset, asyncResult.Count, new AsyncCallback(this.BeginWriteCallback), asyncResult);
                }
            }
            catch (Exception exception)
            {
                _lock.AcquireWriterLock();
                try
                {
                    SetIsWriting(false);
                }
                finally
                {
                    _lock.ReleaseWriterLock();
                }
                if (asyncResult != null)
                {
                    asyncResult.SetComplete(exception);
                }
                throw;
            }
        }
        private void BeginWriteCallback(IAsyncResult asyncResult)
        {
            RtmpAsyncResult asyncState = asyncResult.AsyncState as RtmpAsyncResult;

            if (asyncState != null)
            {
                try
                {
                    this.InternalEndWrite(asyncResult);
                    _lock.AcquireWriterLock();
                    try
                    {
                        SetIsWriting(false);
                    }
                    finally
                    {
                        _lock.ReleaseWriterLock();
                    }
                    asyncState.SetComplete(null);
                }
                catch (Exception exception)
                {
                    _lock.AcquireWriterLock();
                    try
                    {
                        SetIsWriting(false);
                    }
                    finally
                    {
                        _lock.ReleaseWriterLock();
                    }
                    asyncState.SetComplete(exception);
                }
                finally
                {
                    try
                    {
                        this.TryBeginWrite();
                    }
                    catch
                    {
                    }
                }
            }
        }
        public override void EndWrite(IAsyncResult asyncResult)
        {
            RtmpAsyncResult result = asyncResult as RtmpAsyncResult;

            try
            {
                if (!asyncResult.IsCompleted)
                {
                    asyncResult.AsyncWaitHandle.WaitOne();
                }
                if (result.HasException())
                {
                    throw result.Exception;
                }
            }
            finally
            {
                this.TryBeginWrite();
            }
        }
        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
        {
            RtmpAsyncResult asyncResult = null;

            _lock.AcquireWriterLock();
            try
            {
                if (this.IsClosed)
                {
                    throw new ObjectDisposedException(null);
                }
                asyncResult = new RtmpAsyncResult(callback, state, buffer, offset, count);
                _outgoingQueue.Enqueue(asyncResult);
            }
            finally
            {
                _lock.ReleaseWriterLock();
            }
            TryBeginWrite();
            return(asyncResult);
        }
        private void BeginWriteCallback(IAsyncResult asyncResult)
        {
            RtmpAsyncResult asyncState = asyncResult.AsyncState as RtmpAsyncResult;

            if (asyncState != null)
            {
                Queue <RtmpAsyncResult> queue;
                try
                {
                    this.InternalEndWrite(asyncResult);
                    lock ((queue = this._outgoingQueue))
                    {
                        this._isWriting = false;
                    }
                    asyncState.SetComplete(null);
                }
                catch (Exception exception)
                {
                    lock ((queue = this._outgoingQueue))
                    {
                        this._isWriting = false;
                    }
                    asyncState.SetComplete(exception);
                }
                finally
                {
                    try
                    {
                        this.TryBeginWrite();
                    }
                    catch
                    {
                    }
                }
            }
        }