在 .NET 中使用 MemoryCache
时,如果您发现使用对象作为关键字时未命中缓存,可能是由于对象的引用或相等性比较问题。以下是一些可能导致此问题的原因以及解决方案。
当您使用对象作为缓存键时,MemoryCache
使用对象的引用来判断键的相等性。如果您使用的是一个新创建的对象,即使它的属性值与之前的对象相同,MemoryCache
也会认为它是不同的键。
var cacheKey = myObject.Id.ToString(); // 使用 ID 作为键
GetHashCode
和 Equals
方法:如果您确实需要使用对象本身作为键,您需要确保该对象的 GetHashCode
和 Equals
方法被正确重写,以便它们能够基于对象的内容而不是引用进行比较。public class MyObject
{
public int Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
if (obj is MyObject other)
{
return Id == other.Id && Name == other.Name;
}
return false;
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Name);
}
}
确保您在使用 MemoryCache
时,缓存项的生命周期设置正确。如果缓存项在您尝试访问它之前已经过期或被移除,您将无法命中缓存。
var cacheItemPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(10) // 10分钟后过期
};
memoryCache.Set(cacheKey, myObject, cacheItemPolicy);
如果您的应用程序是多线程的,确保在访问和修改缓存时使用适当的线程安全机制。
以下是一个使用 MemoryCache
的示例,展示了如何使用字符串作为键来避免未命中问题:
using System;
using System.Runtime.Caching;
public class Program
{
private static MemoryCache memoryCache = MemoryCache.Default;
public static void Main()
{
var myObject = new MyObject { Id = 1, Name = "Test" };
var cacheKey = myObject.Id.ToString();
// 添加到缓存
memoryCache.Set(cacheKey, myObject, DateTimeOffset.Now.AddMinutes(10));
// 尝试从缓存中获取
var cachedObject = memoryCache.Get(cacheKey) as MyObject;
if (cachedObject != null)
{
Console.WriteLine($"Cache hit: {cachedObject.Name}");
}
else
{
Console.WriteLine("Cache miss");
}
}
}
public class MyObject
{
public int Id { get; set; }
public string Name { get; set; }
}
领取专属 10元无门槛券
手把手带您无忧上云