.NET缓存里分了几类,主要学习内存缓存、分布式缓存
builder.Services.AddMemoryCache();
Get、TryGetValue、GetOrCreate、GetOrCreateAsync、Set、Remove,关键参数是过期时间,GetOrCreate、GetOrCreateAsync是通过委托类型的参数设置的,Set方法可以通过参数直接设置,或者使用MemoryCacheEntryOptions,类型有三种:
(1)AbsoluteExpiration 绝对过期,到期删除
(2)AbsoluteExpirationRelativeToNow 相对当前时间过期,到期删除
(3)SlidingExpiration 滑动过期,时效内访问再延长,未访问到期删除
[Route("api/[controller]/[action]")]
[ApiController]
public class MemoryCacheController : ControllerBase
{
private readonly IMemoryCache _memoryCache;
private readonly string cacheKey = "cache";
public MemoryCacheController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
[HttpGet]
public string Get()
{
var value = _memoryCache.Get(cacheKey);
return value == null ? "null" : value.ToString();
}
[HttpGet]
public string TryGetValue()
{
if (_memoryCache.TryGetValue(cacheKey, out string value))
return value;
return "null";
}
[HttpGet]
public string GetOrCreate()
{
var value = _memoryCache.GetOrCreate(
cacheKey,
cacheEntry =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3);
return "GetOrCreate:" + DateTime.Now.ToString("T");
});
return value;
}
[HttpGet]
public async Task<string> GetOrCreateAsync()
{
var value = await _memoryCache.GetOrCreateAsync(
cacheKey,
cacheEntry =>
{
cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
return Task.FromResult("GetOrCreateAsync:" + DateTime.Now.ToString("T"));
});
return value;
}
[HttpPost]
public void Set()
{
string value = "Set:" + DateTime.Now.ToString("T");
MemoryCacheEntryOptions op = new MemoryCacheEntryOptions();
//绝对到期,到期删除
op.AbsoluteExpiration = DateTimeOffset.Parse("2023-12-31 23:59:59");
//_memoryCache.Set(cacheKey, value, DateTimeOffset.Parse("2023-12-31 23:59:59"));
//相对当前时间过期,到期删除
op.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
//_memoryCache.Set(cacheKey, value, TimeSpan.FromSeconds(10));
//滑动过期,时效内访问再延长,未访问到期删除
op.SlidingExpiration = TimeSpan.FromSeconds(10);
_memoryCache.Set(cacheKey, value, op);
}
[HttpDelete]
public void Remove()
{
_memoryCache.Remove(cacheKey);
}
}
工欲善其事,必先利其器——>Redis安装
(1)先安装Nuget:Microsoft.Extensions.Caching.StackExchangeRedis
(2)appsettings.json配置Redis连接
"Redis": "39.107.109.17:6379,password=shenhuak1"
(3)Program注入
//Redis分布式缓存
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration["Redis"];
options.InstanceName = "RedisInstance";//实例名,配置后实际的key=InstanceName+key
});
IDistributedCache 接口提供方法:Get、GetAsync、Set、SetAsync、Refresh、RefreshAsync、Remove、RemoveAsync
以及拓展方法:GetString、GetStringAsync、SetString、SetStringAsync
过期参数跟内存缓存差不多,直接看代码
[Route("api/[controller]/[action]")]
[ApiController]
public class DistributedController : ControllerBase
{
private readonly IDistributedCache _distributedCache;
private readonly string cacheKey = "cache";
public DistributedController(IDistributedCache distributedCache)
{
_distributedCache = distributedCache;
}
[HttpGet]
public string Get()
{
return _distributedCache.GetString(cacheKey);
}
[HttpGet]
public async Task<string> GetAsync()
{
return await _distributedCache.GetStringAsync(cacheKey);
}
[HttpPost]
public void Set()
{
DistributedCacheEntryOptions op = new DistributedCacheEntryOptions();
//绝对过期,到期删除
op.AbsoluteExpiration = DateTimeOffset.Parse("2023-12-31 23:59:59");//op.SetAbsoluteExpiration(DateTimeOffset.Parse("2023-12-31 23:59:59"));
//相对当前时间过期,到期删除
op.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);//op.SetAbsoluteExpiration(TimeSpan.FromSeconds(10));
//滑动过期,时效内访问再延长,未访问到期删除
op.SlidingExpiration = TimeSpan.FromSeconds(10);//op.SetSlidingExpiration(TimeSpan.FromSeconds(10));
_distributedCache.SetString(cacheKey, DateTime.Now.ToString("T"), op);
}
[HttpPost]
public async Task SetAsync()
{
await _distributedCache.SetStringAsync(cacheKey, DateTime.Now.ToString("T"));
}
[HttpPost]
public void Refresh()
{
_distributedCache.Refresh(cacheKey);
}
[HttpPost]
public async Task RefreshAsync()
{
await _distributedCache.RefreshAsync(cacheKey);
}
[HttpDelete]
public void Remove()
{
_distributedCache.Remove(cacheKey);
}
[HttpDelete]
public async void RemoveAsync()
{
await _distributedCache.RemoveAsync(cacheKey);
}
}
非拓展方法是都是通过byte[]字节数组来向Redis存取数据的不方便,大多情况都会自己封装一个helper类。拓展方法虽然用string类型操作,实际存储到Redis是用的Hash类型,无法操作Redis其他类型及功能。
完整功能需要使用其他客户端:StackExchange.Redis、FreeRedis、NRedisStack 等