我应该在这种情况下使用会话或缓存吗?或者是其他东西?

时间:2014-08-07 18:49:02

标签: asp.net caching asp.net-session asp.net-caching

我必须创建一种机制来存储和读取每个用户的首选项(控制默认值和设置)。我遇到了与网络流量有关的问题,因为数据库可以通过互联网访问,而应用服务器有时连接到差的512Kbps互联网连接。

我的应用程序可以有大约50个并发用户,每个页面/表单最多可以有50个项目(首选项)。页数大约是80。

因此,考虑到性能方面的观点,我应该选择哪种方式来减少网络流量?会话或缓存?

更新

我创建了两个示例页面,一个使用缓存,另一个使用会话。

加载测试 90位用户

存储内容 1000个元素 每个元素的值为20个字符

以下是每个测试用例的结果:

的MemoryCache 分配了330,725,246个总字节数

分配大部分内存的功能

Name   Bytes %
System.Runtime.Caching.MemoryCache.Set(string,object,class System.Runtime.Caching.CacheItemPolicy,string)   34,74
System.Web.UI.Page.ProcessRequest(class System.Web.HttpContext) 18,39
System.String.Concat(string,string) 12,65
System.String.Join(string,string[]) 5,31
System.Collections.Generic.Dictionary`2.Add(!0,!1)  4,42

源代码:

protected void Page_Load(object sender, EventArgs e)
        {
            outputPanel.Text = String.Join(System.Environment.NewLine, ReadEverything().ToArray());
        }

        private IEnumerable<String> ReadEverything()
        {
            for (int i = 0; i < 1000; i++)
            {
                yield return ReadFromCache(i);
            }
        }

        private string ReadFromCache(int p)
        {
            String saida = String.Empty;
            ObjectCache cache = MemoryCache.Default;
            Dictionary<int, string> cachedItems = cache["user" + Session.SessionID] as Dictionary<int, string>;

            if (cachedItems == null)
            {
                cachedItems = new Dictionary<int, string>();
            }

            if (!cachedItems.TryGetValue(p, out saida))
            {
                saida = Util.RandomString(20);
                cachedItems.Add(p, saida);

                CacheItemPolicy policy = new CacheItemPolicy();
                policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(30);
                cache.Set("user" + Session.SessionID, cachedItems, policy);
            }

            return saida;
        }

会话 分配的总字节数为111,625,747

分配大部分内存的功能

Name   Bytes %
System.Web.UI.Page.ProcessRequest(class System.Web.HttpContext) 55,19
System.String.Join(string,string[]) 15,93
System.Collections.Generic.Dictionary`2.Add(!0,!1)  6,00
System.Text.StringBuilder.Append(char)  5,93
System.Linq.Enumerable.ToArray(class System.Collections.Generic.IEnumerable`1) 4,46

源代码:

protected void Page_Load(object sender, EventArgs e)
        {
            outputPanel.Text = String.Join(System.Environment.NewLine, ReadEverything().ToArray());
        }

        private IEnumerable<String> ReadEverything()
        {
            for (int i = 0; i < 1000; i++)
            {
                yield return ReadFromSession(i);
            }
        }

        private string ReadFromSession(int p)
        {
            String saida = String.Empty;
            Dictionary<int, string> cachedItems = Session["cachedItems"] as Dictionary<int, string>;

            if (cachedItems == null)
            {
                cachedItems = new Dictionary<int, string>();
            }

            if (!cachedItems.TryGetValue(p, out saida))
            {
                saida = Util.RandomString(20);
                cachedItems.Add(p, saida);

                Session["cachedItems"] = cachedItems;
            }

            return saida;
        }

我忘了提到我正在创建一个使用ASP.Net和WPF项目的解决方案,但是,如果Session远比MemoryCache选项好,我可以为每个平台提供不同的解决方案。

2 个答案:

答案 0 :(得分:0)

两者都是相同的,它们在内存中...如果你使用的是数据库会话并且连接不良,那么你应该使用缓存(如果存在),如果没有则加载,然后缓存。

答案 1 :(得分:0)

我认为会话是一种缓存机制,与其他会话不同,它只针对特定的浏览器会话。我的方法会考虑以下问题。

  1. 此网站负载均衡吗?如果是,则使用会话将强制执行持久会话,如果您关闭服务器可能会导致问题。

  2. 此数据用户是否具体?如果是,会话是一种简单的方法来隔离数据而无需大量的键操作。它还具有以下优点:当用户的会话超时时,它会自动清理。如果不是,我建议使用添加了.NET 4.0的MemoryCache功能。它支持到期。

  3. 此缓存将如何过时?如果用户A可以修改为用户B缓存的数据,那么您现在正在使用会话缓存提供脏数据。这会提示共享缓存机制。

  4. 编辑:一旦回答了这些问题,您就应该能够确定哪种类型的缓存机制适合您的情况。然后,您可以评估该子集的性能。