我正在尝试编写一个类来处理.net核心类库中的内存缓存。如果我不使用核心,那么我可以写
using System.Runtime.Caching;
using System.Collections.Concurrent;
namespace n{
public class MyCache
{
readonly MemoryCache _cache;
readonly Func<CacheItemPolicy> _cachePolicy;
static readonly ConcurrentDictionary<string, object> _theLock = new ConcurrentDictionary<string, object>();
public MyCache(){
_cache = MemoryCache.Default;
_cachePolicy = () => new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(15),
RemovedCallback = x =>
{
object o;
_theLock.TryRemove(x.CacheItem.Key, out o);
}
};
}
public void Save(string idstring, object value){
lock (_locks.GetOrAdd(idstring, _ => new object()))
{
_cache.Add(idstring, value, _cachePolicy.Invoke());
}
....
}
}
}
在.Net核心中,我找不到System.Runtime.Cache。阅读.net核心In Memory Cache后,我添加了参考Microsoft.Extensions.Caching.Memory(1.1.0)并尝试了
using System.Collections.Concurrent;
using Microsoft.Extensions.Caching.Memory;
namespace n
{
public class MyCache
{
readonly MemoryCache _cache;
readonly Func<CacheItemPolicy> _cachePolicy;
static readonly ConcurrentDictionary<string, object> _theLock = new ConcurrentDictionary<string, object>();
public MyCache(IMemoryCache memoryCache){
_cache = memoryCache;// ?? **MemoryCache**;
}
public void Save(string idstring, object value){
lock (_locks.GetOrAdd(idstring, _ => new object()))
{
_cache.Set(idstring, value,
new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(15))
.RegisterPostEvictionCallback(
(key, value, reason, substate) =>
{
object o;
_locks.TryRemove(key.ToString(), out o);
}
));
}
....
}
}
}
保存方法中的希望代码是可以的,尽管我的大多数mycache测试目前都失败了。任何人都可以指出什么是错的? 主要问题是关于构造函数我该怎么做来设置缓存而不是 MemoryCache.Default
_cache = memoryCache ?? MemoryCache.Default;
答案 0 :(得分:29)
构造函数是:
using Microsoft.Extensions.Caching.Memory;
。 。
MemoryCache myCache = new MemoryCache(new MemoryCacheOptions());
答案 1 :(得分:1)
我的答案集中在“在.Net内核中找不到System.Runtime.Cache”,因为我遇到了同样的问题。对于在特定OP的情况下使用IMemoryCache
,可接受的答案很好。
有两种完全不同的缓存实现/解决方案:
1-System.Runtime.Caching/MemoryCache
2-Microsoft.Extensions.Caching.Memory/IMemoryCache
System.Runtime.Caching / MemoryCache:
这与以前的ASP.Net MVC的HttpRuntime.Cache
几乎相同。 您可以在ASP.Net CORE上使用它,而无需进行任何依赖注入。这是使用方法:
// First install 'System.Runtime.Caching' (NuGet package)
// Add a using
using System.Runtime.Caching;
// To get a value
var myString = MemoryCache.Default["itemCacheKey"];
// To store a value
MemoryCache.Default["itemCacheKey"] = myString;
Microsoft.Extensions.Caching.Memory
这与依赖注入紧密结合。这是一种实施方式:
// In asp.net core's Startup add this:
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
}
在控制器上使用它:
// Add a using
using Microsoft.Extensions.Caching.Memory;
// In your controller's constructor, you add the dependency on the 'IMemoryCache'
public class HomeController : Controller
{
private IMemoryCache _cache;
public HomeController(IMemoryCache memoryCache)
{
_cache = memoryCache;
}
public void Test()
{
// To get a value
string myString = null;
if (_cache.TryGetValue("itemCacheKey", out myString))
{ /* key/value found - myString has the key cache's value*/ }
// To store a value
_cache.Set("itemCacheKey", myString);
}
}
正如@WillC所指出的,该答案实际上是Cache in-memory in ASP.NET Core文档的摘要。您可以在此处找到扩展信息。
答案 2 :(得分:0)
如果您使用Asp.net核心,则无需自定义SingleTon进行缓存,因为Asp.net核心是您的Cache类支持的DI。
要使用 IMemoryCache
将数据设置到服务器的内存中,可以执行以下操作:
public void Add<T>(T o, string key)
{
if (IsEnableCache)
{
T cacheEntry;
// Look for cache key.
if (!_cache.TryGetValue(key, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = o;
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromSeconds(7200));
// Save data in cache.
_cache.Set(key, cacheEntry, cacheEntryOptions);
}
}
}
有关更多详细信息,您可以阅读文章implement in-memory in asp.net core
答案 3 :(得分:0)
private readonly IMemoryCache memoryCache;
private IList<Employee> GetListFromCache()
{
const string Key = "employee";
IList<Employee> cacheValue = null;
if (!this.memoryCache.TryGetValue(Key, out cacheValue))
{
//// Key not in cache, so get data.
cacheValue = this.context.Employee.AsNoTracking().Include(x =>
x.Id).ToList();
//// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
//// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromDays(1));
//// Save data in cache.
this.memoryCache.Set(Key, cacheValue, cacheEntryOptions);
}
return cacheValue;
}
在Startup.cs的ConfigureServices下注册AddMemoryCache
services.AddMemoryCache();
/// <summary>Gets the memory cache.</summary>
/// <returns> Memory cache object.</returns>
public IMemoryCache GetMemoryCache()
{
var services = new ServiceCollection();
services.AddMemoryCache();
var serviceProvider = services.BuildServiceProvider();
return serviceProvider.GetService<IMemoryCache>();
}
//Inject memory cache in constructor for unit test
this.memoryCache = text.GetMemoryCache();