//
        /// <summary>
        /// 归还一个通道
        /// </summary>
        /// <param name="channel">通道对象</param>
        public void ReturnChannel(LibraryChannel channel)
        {
            LibraryChannelWrapper wrapper = null;

            if (this.m_lock.TryEnterWriteLock(m_nLockTimeout) == false)
            {
                throw new LockException("锁定尝试中超时");
            }
            try
            {
                wrapper = _findUsedChannel(channel);
                if (wrapper != null)
                {
                    // wrapper.InUsing = false;
                    MoveToFreeList(wrapper);
                }
            }
            finally
            {
                this.m_lock.ExitWriteLock();
            }

            // testing
            // CleanChannel();
        }
        //
        /// <summary>
        /// 征用一个通道
        /// </summary>
        /// <param name="strUrl">服务器 URL</param>
        /// <param name="strUserName">用户名</param>
        /// <param name="strLang">语言代码。如果为空,表示不在意通道的语言代码</param>
        /// <returns>返回通道对象</returns>
        public LibraryChannel GetChannel(string strUrl,
                                         string strUserName,
                                         string strLang = "")
        {
            LibraryChannelWrapper wrapper = null;

            if (this.m_lock.TryEnterWriteLock(m_nLockTimeout) == false)
            {
                throw new LockException("锁定尝试中超时");
            }
            try
            {
                wrapper = this._findFreeChannel(strUrl, strUserName, strLang);

                if (wrapper != null)
                {
                    LibraryChannel result = wrapper.Channel;
                    return(result);
                }

                if (this._usedList.Count + this._freeList.Count >= MaxCount)
                {
                    // 清理不用的通道
                    int nDeleteCount = _cleanFreeChannel(false);
                    if (nDeleteCount == 0)
                    {
                        // 全部都在使用
                        throw new Exception("通道池已满,请稍后重试获取通道");
                    }
                }

                // 如果没有找到
                LibraryChannel inner_channel = new LibraryChannel();
                inner_channel.Url          = strUrl;
                inner_channel.UserName     = strUserName;
                inner_channel.Lang         = strLang;
                inner_channel.BeforeLogin -= new BeforeLoginEventHandle(channel_BeforeLogin);
                inner_channel.BeforeLogin += new BeforeLoginEventHandle(channel_BeforeLogin);

                inner_channel.AfterLogin -= inner_channel_AfterLogin;
                inner_channel.AfterLogin += inner_channel_AfterLogin;

                wrapper         = new LibraryChannelWrapper();
                wrapper.Channel = inner_channel;
                // wrapper.InUsing = true;

                this._usedList.Add(wrapper);
                return(inner_channel);
            }
            finally
            {
                this.m_lock.ExitWriteLock();
            }
        }
        // 清理处在未使用状态的通道
        // parameters:
        //      strUserName 希望清除用户名为此值的全部通道。如果本参数值为空,则表示清除全部通道
        // return:
        //      清理掉的通道数目
        int _cleanFreeChannel(bool bLock, string strUserName = "")
        {
            List <LibraryChannelWrapper> deletes = new List <LibraryChannelWrapper>();

            if (bLock == true)
            {
                if (this.m_lock.TryEnterWriteLock(m_nLockTimeout) == false)
                {
                    throw new LockException("锁定尝试中超时");
                }
            }
            try
            {
                for (int i = 0; i < this._freeList.Count; i++)
                {
                    LibraryChannelWrapper wrapper = this._freeList[i];
                    if (string.IsNullOrEmpty(strUserName) == true || wrapper.Channel.UserName == strUserName)
                    {
                        this._freeList.RemoveAt(i);
                        i--;
                        deletes.Add(wrapper);
                    }
                }
            }
            finally
            {
                if (bLock == true)
                {
                    this.m_lock.ExitWriteLock();
                }
            }

            foreach (LibraryChannelWrapper wrapper in deletes)
            {
                wrapper.Channel.BeforeLogin -= new BeforeLoginEventHandle(channel_BeforeLogin);
                wrapper.Channel.AfterLogin  -= inner_channel_AfterLogin;
                wrapper.Channel.Close();
            }

            return(deletes.Count);
        }
 LibraryChannelWrapper MoveToFreeList(LibraryChannelWrapper wrapper)
 {
     this._usedList.Remove(wrapper);
     this._freeList.Add(wrapper);
     return(wrapper);
 }