示例#1
0
        internal static int m_nLockTimeout   = 5000;    // 5000=5秒

        //
        /// <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     = null,
                                         string strClientIP = null)
        {
            LibraryChannelWrapper wrapper = null;

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

                // 如果没有找到
                LibraryChannel inner_channel = new LibraryChannel();
                inner_channel.Url      = strUrl;
                inner_channel.UserName = strUserName;
                if (strLang != null)
                {
                    inner_channel.Lang = strLang;
                }
                if (strClientIP != null)
                {
                    inner_channel.ClientIP = strClientIP;
                }

                // test
                // inner_channel.ClientIP = "test:127.0.0.1";

                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;

                if (this.Count >= MaxCount)
                {
                    // TODO: 这一个部分放在写锁定范围内,是否会导致其他请求排队超时?
                    // 清理不用的通道
                    int nDeleteCount = _cleanChannel(false,
                                                     (channel) => { return(true); });
                    if (nDeleteCount == 0)
                    {
                        inner_channel?.Dispose();
                        // 全部都在使用
                        throw new Exception("通道池已满,请稍后重试获取通道");
                    }
                }

                this.Add(wrapper);
                return(inner_channel);
            }
            finally
            {
                this.m_lock.ExitWriteLock();
            }
        }