javascript

java

python

c#

android

node.js

c++

reactjs

php

html

jquery

css

.net

ios

git

ruby-on-rails

sql

c

string

ruby

asp.net-MemoryCache空:被s后返回null

我在使用新的.NET 4 System.Runtime.Caching MemoryCache的MVC 3应用程序遇到问题。 我注意到,在看似不可预测的时间之后,它停止缓存内容,并表现为空。 考虑一下我直接从ASP.NET MVC中的测试视图获取的以下代码:

MemoryCache.Default.Set("myname","fred", new CacheItemPolicy() { SlidingExpiration = new TimeSpan(0,5,0) });
Response.Write(MemoryCache.Default["myname"]);

当它工作时,可以预见地显示“ fred”。 但是,当问题开始发生时,尽管有MemoryCache.Default,但MemoryCache.Default.Dispose()的值为空。 我可以通过在Response.Write()行上设置一个断点并使用“即时窗口”直接设置缓存并从缓存中读取来证明这一点-它只是不会设置它,而是保持为空! 然后使其再次正常工作的唯一方法是导致AppDomain回收。

有趣的是,通过中断MemoryCache.Default行并运行MemoryCache.Default.Dispose(),可以激发该问题在应用正常运行时发生。此后,MemoryCache.Default本身不为null(这是为什么?),但不会保存任何设置 。 它不会导致任何错误,但不会保存任何内容。

有人可以验证并解释吗? 正如我所相信的那样,当该应用程序停止自行运行时,正在处理MemoryCache.Default,但这不是我!


更新

好吧,我现在厌倦了这个问题! CLRProfiler似乎不适用于MVC3。SciTech的CLR工具很好-RedGate ANTS也是如此。 但是他们告诉我的只是MemoryCache对象正在被某种东西处置! 我还证明了(通过时间戳打印)应该在页面上缓存的PartialView(由OutputCacheAttribute指定)在几分钟后停止缓存-它在每次调用页面时开始刷新。 为了阐明环境,我直接在运行Win 7 Ultimate的开发工作站上的IIS 7.5服务器上运行。 上面提到的内存工具建议我仅使用9mb的内存来播放游戏对象。

无奈之下,我将缓存代码更改为首先搜索环境HttpContext,以使其挂接并使用其缓存功能(如果可用)。 早期测试表明这是可靠的,但感觉就像是一个讨厌的黑客。

我感到不保证MemoryCache和OutputCache可以与MVC 3一起使用...

trans by 2020-01-20T19:47:21Z

CodeGo.net>如何处理使用MemoryCache昂贵的建设运作?

在ASP.NET MVC项目中,我们有几个数据实例,这些实例需要大量的资源和时间来构建。 我们要缓存它们。

key提供了一定级别的线程安全性,但不足以避免并行运行多个构建代码实例。 这是一个例子:

var data = cache["key"];
if(data == null)
{
  data = buildDataUsingGoodAmountOfResources();
  cache["key"] = data;
}

如您所见,在繁忙的网站上,数百个线程可以同时进入if语句,直到构建数据为止,并使构建操作更加缓慢,从而不必要地消耗了服务器资源。

在MemoryCache中有一个原子key实现,但是它错误地要求“设置值”而不是“代码来检索要设置的值”,我认为这使给定的方法几乎完全无用。

我们一直在围绕MemoryCache使用我们自己的临时支架,以使其正确运行,但是它需要显式的keys。 使用每个条目的锁定对象很麻烦,并且我们通常通过共享锁定对象来逃避这远非理想。 这使我认为避免这种约定的原因可能是故意的。

所以我有两个问题:

  • 是否最好不要使用key建筑法规? (我想这可能证明对某人有更好的响应能力)

  • 对于此类锁定,为MemoryCache实现每个条目锁定的正确方法是什么? 使用key字符串作为锁定对象的强烈要求在“ .NET锁定101”处被取消。

trans by 2019-10-14T08:05:49Z

CodeGo.net>的MemoryCache线程安全,是否需要锁定?

首先,让我把它扔在那里,我知道下面的代码不是线程安全的(更正:可能)。 我正在努力寻找的是一种实现,而我实际上可能在测试中失败。 我现在正在重构一个大型WCF项目,该项目需要一些(主要是)静态数据进行缓存,并从SQL数据库填充该数据。 它需要至少每天一次过期并“刷新”,这就是为什么我要使用MemoryCache。

我知道下面的代码不应该是线程安全的,但是我无法使它在重负载下失败,并且使Google搜索显示两种实现方式的复杂情况变得复杂(带有和不带有锁以及是否需要锁的辩论。)

能够在多线程环境中拥有MemoryCache知识的人可以让我明确地知道是否需要在适当的地方锁定,以便在检索/重新填充期间不会引发对remove的调用(很少调用,但这是必需的)。

public class MemoryCacheService : IMemoryCacheService
{
    private const string PunctuationMapCacheKey = "punctuationMaps";
    private static readonly ObjectCache Cache;
    private readonly IAdoNet _adoNet;

    static MemoryCacheService()
    {
        Cache = MemoryCache.Default;
    }

    public MemoryCacheService(IAdoNet adoNet)
    {
        _adoNet = adoNet;
    }

    public void ClearPunctuationMaps()
    {
        Cache.Remove(PunctuationMapCacheKey);
    }

    public IEnumerable GetPunctuationMaps()
    {
        if (Cache.Contains(PunctuationMapCacheKey))
        {
            return (IEnumerable) Cache.Get(PunctuationMapCacheKey);
        }

        var punctuationMaps = GetPunctuationMappings();

        if (punctuationMaps == null)
        {
            throw new ApplicationException("Unable to retrieve punctuation mappings from the database.");
        }

        if (punctuationMaps.Cast<IPunctuationMapDto>().Any(p => p.UntaggedValue == null || p.TaggedValue == null))
        {
            throw new ApplicationException("Null values detected in Untagged or Tagged punctuation mappings.");
        }

        // Store data in the cache
        var cacheItemPolicy = new CacheItemPolicy
        {
            AbsoluteExpiration = DateTime.Now.AddDays(1.0)
        };

        Cache.AddOrGetExisting(PunctuationMapCacheKey, punctuationMaps, cacheItemPolicy);

        return punctuationMaps;
    }

    //Go oldschool ADO.NET to break the dependency on the entity framework and need to inject the database handler to populate cache
    private IEnumerable GetPunctuationMappings()
    {
        var table = _adoNet.ExecuteSelectCommand("SELECT [id], [TaggedValue],[UntaggedValue] FROM [dbo].[PunctuationMapper]", CommandType.Text);
        if (table != null && table.Rows.Count != 0)
        {
            return AutoMapper.Mapper.DynamicMap<IDataReader, IEnumerable<PunctuationMapDto>>(table.CreateDataReader());
        }

        return null;
    }
}
trans by 2019-10-06T07:48:51Z

CodeGo.net>使用MemoryCach的多个实例

我想使用2548832834043773973952命名空间为应用程序添加缓存功能,并且可能希望在多个地方和不同的上下文中使用缓存。为此,我想使用几个MemoryCache实例。

但是,我在这里不建议使用一个以上的MemoryCache实例:

MemoryCache不是单例,但是您应该仅创建几个或可能仅创建一个MemoryCache实例,并且用于缓存项目的代码应使用这些实例。

多个MemoryCache实例将如何影响我的应用程序?我觉得这很奇怪,因为在我看来,在应用程序中使用多个缓存是很常见的情况。

编辑:更具体地说,我有一个应该为每个实例保留缓存的类。 我应该避免使用MemoryCache并寻找其他缓存解决方案吗? 在这种情况下使用MemoryCache是否被认为是不好的,如果是这样,为什么?

trans by 2019-09-30T16:13:38Z

c# - MemoryCache在配置中不遵守内存限制

我正在使用应用程序中的.NET 4.0 MemoryCache类并尝试限制最大缓存大小,但在我的测试中,似乎缓存实际上并未遵守限制。

我使用的设置,根据MSDN,应该限制缓存大小:

  1. CacheMemoryLimitMegabytes:对象实例可以增长到的最大内存大小(以兆字节为单位)。“
  2. PhysicalMemoryLimitPercentage:“缓存可以使用的物理内存百分比,表示为1到100之间的整数值。默认值为零,表示MemoryCache实例根据计算机上安装的内存量管理自己的内存1“。 1.这不完全正确 - 忽略任何低于4的值并替换为4。

我理解这些值是近似值而不是硬限制,因为清除缓存的线程每隔x秒触发一次,并且还取决于轮询间隔和其他未记录的变量。 然而,即使考虑到这些差异,在将测试应用程序中的CacheMemoryLimitMegabytes和PhysicalMemoryLimitPercentage一起或单独设置后,当第一项从缓存中逐出时,我看到了非常不一致的缓存大小。 为了确保我每次测试10次并计算出平均值。

这些是在具有3GB RAM的32位Windows 7 PC上测试以下示例代码的结果。 在每次测试第一次调用CacheItemRemoved()之后获取缓存的大小。 (我知道缓存的实际大小将大于此)

MemLimitMB    MemLimitPct     AVG Cache MB on first expiry    
   1            NA              84
   2            NA              84
   3            NA              84
   6            NA              84
  NA             1              84
  NA             4              84
  NA            10              84
  10            20              81
  10            30              81
  10            39              82
  10            40              79
  10            49              146
  10            50              152
  10            60              212
  10            70              332
  10            80              429
  10           100              535
 100            39              81
 500            39              79
 900            39              83
1900            39              84
 900            41              81
 900            46              84

 900            49              1.8 GB approx. in task manager no mem errros
 200            49              156
 100            49              153
2000            60              214
   5            60              78
   6            60              76
   7           100              82
  10           100              541

这是测试应用程序:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
namespace FinalCacheTest
{       
    internal class Cache
    {
        private Object Statlock = new object();
        private int ItemCount;
        private long size;
        private MemoryCache MemCache;
        private CacheItemPolicy CIPOL = new CacheItemPolicy();

        public Cache(long CacheSize)
        {
            CIPOL.RemovedCallback = new CacheEntryRemovedCallback(CacheItemRemoved);
            NameValueCollection CacheSettings = new NameValueCollection(3);
            CacheSettings.Add("CacheMemoryLimitMegabytes", Convert.ToString(CacheSize)); 
            CacheSettings.Add("physicalMemoryLimitPercentage", Convert.ToString(49));  //set % here
            CacheSettings.Add("pollingInterval", Convert.ToString("00:00:10"));
            MemCache = new MemoryCache("TestCache", CacheSettings);
        }

        public void AddItem(string Name, string Value)
        {
            CacheItem CI = new CacheItem(Name, Value);
            MemCache.Add(CI, CIPOL);

            lock (Statlock)
            {
                ItemCount++;
                size = size + (Name.Length + Value.Length * 2);
            }

        }

        public void CacheItemRemoved(CacheEntryRemovedArguments Args)
        {
            Console.WriteLine("Cache contains {0} items. Size is {1} bytes", ItemCount, size);

            lock (Statlock)
            {
                ItemCount--;
                size = size - 108;
            }

            Console.ReadKey();
        }
    }
}

namespace FinalCacheTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int MaxAdds = 5000000;
            Cache MyCache = new Cache(1); // set CacheMemoryLimitMegabytes

            for (int i = 0; i < MaxAdds; i++)
            {
                MyCache.AddItem(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            }

            Console.WriteLine("Finished Adding Items to Cache");
        }
    }
}

为什么MemoryCache不遵守配置的内存限制?

trans by 2019-09-16T22:13:59Z

c# - 如何清除MemoryCache?

我使用MemoryCache类创建了一个缓存。 我添加了一些项目,但是当我需要重新加载缓存时,我想首先清除它。 最快的方法是什么? 我应该遍历所有项目并一次删除一个项目还是有更好的方法?

trans by 2019-09-11T17:13:58Z

.net - MemoryCache.Add和MemoryCache.Set有什么区别?

我阅读了MSDN文档但没有真正理解它。

我相信Set的行为是“替换现有的,或添加”(原子地)。

那是对的吗?

trans by 2019-09-11T11:30:34Z

c# - 正确使用.NET MemoryCach的锁定模式

我假设此代码存在并发问题:

const string CacheKey = "CacheKey";
static string GetCachedData()
{
    string expensiveString =null;
    if (MemoryCache.Default.Contains(CacheKey))
    {
        expensiveString = MemoryCache.Default[CacheKey] as string;
    }
    else
    {
        CacheItemPolicy cip = new CacheItemPolicy()
        {
            AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(20))
        };
        expensiveString = SomeHeavyAndExpensiveCalculation();
        MemoryCache.Default.Set(CacheKey, expensiveString, cip);
    }
    return expensiveString;
}

并发问题的原因是多个线程可以获取空键,然后尝试将数据插入缓存。

什么是最简洁,最干净的方法来使这个代码并发证明? 我喜欢在缓存相关代码中遵循一个好的模式。 链接到在线文章将是一个很大的帮助。

更新:

我根据@Scott Chamberlain的回答提出了这个代码。 任何人都可以找到任何性能或并发问题吗?如果这样做,它将节省许多代码和错误。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Caching;

namespace CachePoc
{
    class Program
    {
        static object everoneUseThisLockObject4CacheXYZ = new object();
        const string CacheXYZ = "CacheXYZ";
        static object everoneUseThisLockObject4CacheABC = new object();
        const string CacheABC = "CacheABC";

        static void Main(string[] args)
        {
            string xyzData = MemoryCacheHelper.GetCachedData<string>(CacheXYZ, everoneUseThisLockObject4CacheXYZ, 20, SomeHeavyAndExpensiveXYZCalculation);
            string abcData = MemoryCacheHelper.GetCachedData<string>(CacheABC, everoneUseThisLockObject4CacheXYZ, 20, SomeHeavyAndExpensiveXYZCalculation);
        }

        private static string SomeHeavyAndExpensiveXYZCalculation() {return "Expensive";}
        private static string SomeHeavyAndExpensiveABCCalculation() {return "Expensive";}

        public static class MemoryCacheHelper
        {
            public static T GetCachedData<T>(string cacheKey, object cacheLock, int cacheTimePolicyMinutes, Func<T> GetData)
                where T : class
            {
                //Returns null if the string does not exist, prevents a race condition where the cache invalidates between the contains check and the retreival.
                T cachedData = MemoryCache.Default.Get(cacheKey, null) as T;

                if (cachedData != null)
                {
                    return cachedData;
                }

                lock (cacheLock)
                {
                    //Check to see if anyone wrote to the cache while we where waiting our turn to write the new value.
                    cachedData = MemoryCache.Default.Get(cacheKey, null) as T;

                    if (cachedData != null)
                    {
                        return cachedData;
                    }

                    //The value still did not exist so we now write it in to the cache.
                    CacheItemPolicy cip = new CacheItemPolicy()
                    {
                        AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddMinutes(cacheTimePolicyMinutes))
                    };
                    cachedData = GetData();
                    MemoryCache.Default.Set(cacheKey, cachedData, cip);
                    return cachedData;
                }
            }
        }
    }
}
trans by 2019-07-31T16:42:33Z

c# - MemoryCache在配置中不遵守内存限制

我正在使用应用程序中的.NET 4.0 MemoryCache类并尝试限制最大缓存大小,但在我的测试中,似乎缓存实际上并未遵守限制。

我使用的设置,根据MSDN,应该限制缓存大小:

  1. CacheMemoryLimitMegabytes:对象实例可以增长到的最大内存大小(以兆字节为单位)。“
  2. PhysicalMemoryLimitPercentage:“缓存可以使用的物理内存百分比,表示为1到100之间的整数值。默认值为零,表示MemoryCache实例根据计算机上安装的内存量管理自己的内存1“。 1.这不完全正确 - 忽略任何低于4的值并替换为4。

我理解这些值是近似值而不是硬限制,因为清除缓存的线程每隔x秒触发一次,并且还取决于轮询间隔和其他未记录的变量。 然而,即使考虑到这些差异,在将测试应用程序中的CacheMemoryLimitMegabytes和PhysicalMemoryLimitPercentage一起或单独设置后,当第一项从缓存中逐出时,我看到了非常不一致的缓存大小。 为了确保我每次测试10次并计算出平均值。

这些是在具有3GB RAM的32位Windows 7 PC上测试以下示例代码的结果。 在每次测试第一次调用CacheItemRemoved()之后获取缓存的大小。 (我知道缓存的实际大小将大于此)

MemLimitMB    MemLimitPct     AVG Cache MB on first expiry    
   1            NA              84
   2            NA              84
   3            NA              84
   6            NA              84
  NA             1              84
  NA             4              84
  NA            10              84
  10            20              81
  10            30              81
  10            39              82
  10            40              79
  10            49              146
  10            50              152
  10            60              212
  10            70              332
  10            80              429
  10           100              535
 100            39              81
 500            39              79
 900            39              83
1900            39              84
 900            41              81
 900            46              84

 900            49              1.8 GB approx. in task manager no mem errros
 200            49              156
 100            49              153
2000            60              214
   5            60              78
   6            60              76
   7           100              82
  10           100              541

这是测试应用程序:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
namespace FinalCacheTest
{       
    internal class Cache
    {
        private Object Statlock = new object();
        private int ItemCount;
        private long size;
        private MemoryCache MemCache;
        private CacheItemPolicy CIPOL = new CacheItemPolicy();

        public Cache(long CacheSize)
        {
            CIPOL.RemovedCallback = new CacheEntryRemovedCallback(CacheItemRemoved);
            NameValueCollection CacheSettings = new NameValueCollection(3);
            CacheSettings.Add("CacheMemoryLimitMegabytes", Convert.ToString(CacheSize)); 
            CacheSettings.Add("physicalMemoryLimitPercentage", Convert.ToString(49));  //set % here
            CacheSettings.Add("pollingInterval", Convert.ToString("00:00:10"));
            MemCache = new MemoryCache("TestCache", CacheSettings);
        }

        public void AddItem(string Name, string Value)
        {
            CacheItem CI = new CacheItem(Name, Value);
            MemCache.Add(CI, CIPOL);

            lock (Statlock)
            {
                ItemCount++;
                size = size + (Name.Length + Value.Length * 2);
            }

        }

        public void CacheItemRemoved(CacheEntryRemovedArguments Args)
        {
            Console.WriteLine("Cache contains {0} items. Size is {1} bytes", ItemCount, size);

            lock (Statlock)
            {
                ItemCount--;
                size = size - 108;
            }

            Console.ReadKey();
        }
    }
}

namespace FinalCacheTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int MaxAdds = 5000000;
            Cache MyCache = new Cache(1); // set CacheMemoryLimitMegabytes

            for (int i = 0; i < MaxAdds; i++)
            {
                MyCache.AddItem(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            }

            Console.WriteLine("Finished Adding Items to Cache");
        }
    }
}

为什么MemoryCache不遵守配置的内存限制?

trans by 2019-04-05T11:18:18Z

1 共1页