当前位置:编程学习 > C#/ASP.NET >>

ASP.NET使用Dictionary出错

我先描述一下场景:系统面向多个企业用户,登陆时需要保存登录信息,割------------------------------------------------------------------------------------------------------------------

贴代码:

        private static string app_user = "app_user";

        /// <summary>
        /// 用户登录处理Application["LoginUserList"]
        /// </summary>
        /// <param name="loginUser"></param>
        public void Login(LoginUser loginUser)
        {
            try
            {
                lock (app_user)
                {
                    Dictionary<string, List<string>> LoginUserList = Application["LoginUserList"] as Dictionary<string, List<string>>;
                    if (LoginUserList == null)
                    {
                        LoginUserList = new Dictionary<string, List<string>>();
                    }

                    //判断LoginUserList是否存在企业enterpriseID

                    //如果包含,则找到企业key
                    if (LoginUserList.ContainsKey(loginUser.Enterprise_Code))
                    {
                        List<string> list = LoginUserList[loginUser.Enterprise_Code];
                        //如果该企业不包含user,则添加
                        if (!list.Contains(loginUser.UserID))
                        {
                            LoginUserList[loginUser.Enterprise_Code].Add(loginUser.UserID);
                        }
                    }
                    //如果不包含,则添加
                    else
                    {
                        LoginUserList.Add(loginUser.Enterprise_Code, new List<string> { loginUser.UserID });
                    }

                    Application["LoginUserList"] = LoginUserList;
                }
            }
            catch (Exception ex)
            {
                string errorTitle = "保存用户登录信息出错";
                string errorMsg = " 登陆人:" + loginUser.UserID + ", 登录时间:" + DateTime.Now + ", 错误信息:" + ex.Message;
                Utility.Log.log.Error(errorTitle + errorMsg);
                Model.Sys_Email model = new Model.Sys_Email(errorTitle, errorMsg);
                new DAL.Sys_Email().Add(model);
            }
        }


简单讲解一下:Dictionary<string, List<string>> 第一个参数是企业ID,第二个参数是企业下的在线用户集合

再贴出下线代码:

        /// <summary>
        /// 用户注销处理Application["LoginUserList"]
        /// </summary>
        /// <param name="userID">用户ID</param>
        /// <param name="enterpriseID">用户所属企业ID</param>
        public void Logoff(string userID, string enterpriseID)
        {
            try
            {
                lock (app_user)
                {
                    Dictionary<string, List<string>> LoginUserList = Application["LoginUserList"] as Dictionary<string, List<string>>;
                    if (LoginUserList == null)
                    {
                        return;
                    }

                    if (LoginUserList.ContainsKey(enterpriseID))
                    {
                        LoginUserList[enterpriseID].Remove(userID);
                        if (LoginUserList[enterpriseID].Count == 0)
                        {
                            LoginUserList.Remove(enterpriseID);
                        }
                        //注销掉Application[userid]
                        Application.Remove(userID);
                        Application.Remove(userID + "_ip");
                    }

                    Application["LoginUserList"] = LoginUserList;
                }
            }
            catch (Exception ex)
            {
                string errorTitle = "用户注销时出错";
                string errorMsg = " 登陆人:" + userID + ", 登录时间:" + DateTime.Now + ", 错误信息:" + ex.Message;
                Utility.Log.log.Error(errorTitle + errorMsg);
                Model.Sys_Email model = new Model.Sys_Email(errorTitle, errorMsg);
                new DAL.Sys_Email().Add(model);
            }
        }



有的时候用户直接关闭浏览器,这时我会在session_end事件里执行下线操作

Ok,以上场景和代码介绍完毕,问题来了,有时候用户登录,会报错,错误日志如下:
There was an error in serializing one of the headers in message UserPassIsEditedRequest: 'Hashtable insert failed. Load factor too high. The most common cause is multiple threads writing to the Hashtable simultaneously.'.  Please see InnerException for more details.
期大概意思是:哈希表插入失败了。负载率过高。最常见的原因是多个线程同时写入Hashtable。
为这个问题纠结了很久,也看了很多关于Hashtable和Dictionary的安全性问题,加了lock锁,还是会发生以上错误,请教各位大侠们解释。 --------------------编程问答-------------------- --------------------编程问答-------------------- 有人问为什么加字符串锁,这里我也搞不清楚深意。。。只是之前查了很多资料说这样有用,就加了,看来是没什么作用,有人出主意说加全局锁,试试看,不知道可否重现 --------------------编程问答-------------------- 这个,不是蛮清楚,帮忙顶一下 --------------------编程问答-------------------- Application应该是全局的,所有client访问的时候都是在共享同一个,app_user也是全局静态的,看起来不应该有问题,写点日志吧,看下在那行代码出的问题~~~ --------------------编程问答--------------------
       private static Int32 _timeout = 50 * 1000;

        private static ReaderWriterLock rwl = new ReaderWriterLock();

        public static Dictionary<int, ChatInfo> dictChats = new Dictionary<int, ChatInfo>();

        public static List<ChatInfo> Chats = new List<ChatInfo>();

        public static void Add(ChatInfo chat)
        {
            rwl.AcquireWriterLock(_timeout);

            Chats.Add(chat);
            dictChats.Add(chat.ChatID, chat);

            rwl.ReleaseWriterLock();
        }
楼主  加上锁试下 --------------------编程问答-------------------- 为什么不用ConcurrentDictionary<T1, T2>呢
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,