C# 使用 HttpRuntime.Cache 的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1029823/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Issue using HttpRuntime.Cache
提问by user74042
Am using following .net code to add objects to cache:
我正在使用以下 .net 代码将对象添加到缓存:
public static void Add<T>(string key, T dataToCache)
{
try
{
ApplicationLog.Instance.WriteInfoFormat("Inserting item with key {0} into Cache...", key);
HttpRuntime.Cache.Insert(
key,
dataToCache,
null,
DateTime.Now.AddDays(7),
System.Web.Caching.Cache.NoSlidingExpiration);
}
catch (Exception ex)
{
ApplicationLog.Instance.WriteException(ex);
}
}
and here is my code to retrieve values from cache:
这是我从缓存中检索值的代码:
public static T Get<T>(string key)
{
try
{
if (Exists(key))
{
ApplicationLog.Instance.WriteInfoFormat("Retrieving item with key {0} from Cache...", key);
return (T)HttpRuntime.Cache[key];
}
else
{
ApplicationLog.Instance.WriteInfoFormat("Item with key {0} does not exist in Cache.", key);
return default(T);
}
}
catch(Exception ex)
{
ApplicationLog.Instance.WriteException(ex);
return default(T);
}
}
public static bool Exists(string key)
{
bool retVal = false;
try
{
retVal= HttpRuntime.Cache[key] != null;
}
catch (Exception ex)
{
ApplicationLog.Instance.WriteException(ex);
}
return retVal;
}
But i find that after every 2 minutes or so,the cached object value is getting set to null resulting in pulling that value from database again.
但我发现每隔 2 分钟左右,缓存的对象值就会被设置为 null,导致再次从数据库中提取该值。
What am i missing here?
我在这里缺少什么?
采纳答案by colithium
When you say every two minutes the value inserted is set to null, does that mean just the item you're interested in or every single item in the cache?
当您说每两分钟插入的值设置为 null 时,这是否仅表示您感兴趣的项目或缓存中的每个项目?
I ask this because the cache only exists as long as the application is running. If the application is restarted, the cache goes away. This would explain the behavior if everything goes away every 2 minutes. In that case you have a different problem on your hands: why does the application restart every 2 minutes.
我问这个是因为缓存只在应用程序运行时才存在。如果应用程序重新启动,缓存就会消失。如果一切每 2 分钟消失一次,这将解释这种行为。在这种情况下,您会遇到不同的问题:为什么应用程序每 2 分钟重新启动一次。
If it's only SOME items then it could be a memory issue. The cache cleans itself up in response to low memory. I believe there's a way to set priority on values inserted. But this should only be a problem when you're low on memory.
如果它只是一些项目,那么它可能是一个内存问题。缓存会在内存不足时自行清理。我相信有一种方法可以为插入的值设置优先级。但这应该只在您内存不足时才成为问题。
If this still doesn't solve your problem, there is a way to discover why an item is being removed. It is explained here.
如果这仍然不能解决您的问题,则有一种方法可以找出删除某个项目的原因。它解释here。
回答by Tetraneutron
It could be because memory is running low, the cache will automatically kill off items in the cache when memory is becoming scarce, There is an optional parameter to set the priority of items in the cache if you want one item to be cleared before another.
可能是因为内存不足,缓存会在内存不足时自动杀死缓存中的项目,如果您希望一个项目在另一个项目之前被清除,则有一个可选参数来设置缓存中项目的优先级。
回答by user134706
Well first of all your access isn't synchronized so that's a great source of problems. Reading from the HttpRuntime Cache is guarantied to be thread safe so you should really try reading your item as your first step on each and every cache operation.
首先,您的访问不是同步的,因此这是一个很大的问题来源。从 HttpRuntime Cache 读取保证是线程安全的,因此您应该真正尝试将读取您的项目作为每个缓存操作的第一步。
Between checking if Exists
and actually retrieving the item lots of things can happen (such as your item not beeing there anymore). You should get a handle of the item you're looking for, and if it isn't there provide thread-safe insert by fetching it from your persistent data store.
在检查是否Exists
和实际检索项目之间可能会发生很多事情(例如您的项目不再存在)。您应该获得您正在寻找的项目的句柄,如果它不存在,则通过从您的持久数据存储中获取它来提供线程安全插入。
So your Add
logic would get inside your Get
IF the data isn't there. There's nothing fundamentally wrong in providing separate Add
logic and you should measure the cost of hitting the database multiple times compared to blocking further requests for that specific piece of data.
因此,如果数据不存在,您的Add
逻辑就会进入您Get
的内部。提供单独的Add
逻辑从根本上没有错,与阻止对该特定数据的进一步请求相比,您应该衡量多次访问数据库的成本。
T GetT(string key)
{
T item = (cache.Get(key) as T);
if (item == null)
{
lock (yourSyncRoot)
{
// double check it here
item = (cache.Get(key) as T);
if (item != null)
return item;
item = GetMyItemFromMyPersistentStore(key); // db?
if (item == null)
return null;
string[] dependencyKeys = {your, dependency, keys};
cache.Insert(key, item, new CacheDependency(null, dependencyKeys),
absoluteExpiration, slidingExpiration, priority, null);
}
}
return item;
}
Depending on your expiration policy you'll get your data in memory and provide fast & synchronized access to it, but as I said, measure it and adjust it to your needs. In your business logic after updating your item and properly saving it to your persistent store, just remove it from cache and the next call to your Get
will fetch it again.
根据您的到期策略,您将获得内存中的数据并提供对其的快速同步访问,但正如我所说,测量它并根据您的需要进行调整。在更新项目并将其正确保存到持久存储后的业务逻辑中,只需将其从缓存中删除,下一次调用Get
将再次获取它。