C# 在IMemoryCache上调用扩展方法GetOrCreateAync时是否可以避免缓存?
我正在使用C# 在IMemoryCache上调用扩展方法GetOrCreateAync时是否可以避免缓存?,c#,.net,.net-core,memorycache,C#,.net,.net Core,Memorycache,我正在使用IMemoryCache缓存从身份服务器检索到的令牌 在过去,我使用了库中提供的扩展方法。 这非常有用,因为我可以同时定义函数和过期日期 但是,对于令牌,在请求完成之前,我不知道将在x秒值内过期。 我想通过根本不缓存令牌来说明不存在的值的用例 我试过以下方法 var token = await this.memoryCache.GetOrCreateAsync<string>("SomeKey", async cacheEntry => {
IMemoryCache
缓存从身份服务器检索到的令牌
在过去,我使用了库中提供的扩展方法。
这非常有用,因为我可以同时定义函数和过期日期
但是,对于令牌,在请求完成之前,我不知道将在x秒值内过期。
我想通过根本不缓存令牌来说明不存在的值的用例
我试过以下方法
var token = await this.memoryCache.GetOrCreateAsync<string>("SomeKey", async cacheEntry =>
{
var jwt = await GetTokenFromServer();
var tokenHasValidExpireValue = int.TryParse(jwt.ExpiresIn, out int tokenExpirationSeconds);
if (tokenHasValidExpireValue)
{
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(tokenExpirationSeconds);
}
else // Do not cache value. Just return it.
{
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(0); //Exception thrown. Value needs to be positive.
}
return jwt.token;
}
var-token=wait this.memoryCache.GetOrCreateAsync(“SomeKey”,async-cacheEntry=>
{
var jwt=await GetTokenFromServer();
var-tokenHasValidExpireValue=int.TryParse(jwt.ExpiresIn,out int-tokenexpireationseconds);
if(令牌hasvalidexpirevalue)
{
cacheEntry.AbsoluteExpirationRelativeToNow=TimeSpan.FromSeconds(tokenExpirationSeconds);
}
else//不缓存值。只需返回它即可。
{
cacheEntry.AbsoluteExpirationRelativeToNow=TimeSpan.FromSeconds(0);//引发异常。值必须为正数。
}
返回jwt.token;
}
如您所见,当我尝试设置无时间过期TimeSpan.FromSeconds(0)
时,会引发异常
除了分别调用Get
和Set
方法外,还有其他解决方法吗?
如果可能的话,我想使用这个方法。你不能用current实现这一点,因为它总是在调用工厂方法之前创建一个条目。也就是说,你可以用一种类似于
GetOrCreateAsync
的方式将行为封装在你自己的扩展中
public static class CustomMemoryCacheExtensions
{
public static async Task<TItem> GetOrCreateIfValidTimestampAsync<TItem>(
this IMemoryCache cache, object key, Func<Task<(int, TItem)>> factory)
{
if (!cache.TryGetValue(key, out object result))
{
(int tokenExpirationSeconds, TItem factoryResult) =
await factory().ConfigureAwait(false);
if (tokenExpirationSeconds <= 0)
{
// if the factory method did not return a positive timestamp,
// return the data without caching.
return factoryResult;
}
// since we have a valid timestamp:
// 1. create a cache entry
// 2. Set the result
// 3. Set the timestamp
using ICacheEntry entry = cache.CreateEntry(key);
entry.Value = result;
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(tokenExpirationSeconds);
}
return (TItem)result;
}
}
公共静态类CustomMemoryCacheExtensions
{
公共静态异步任务GetOrCreateIfValidTimestampAsync(
此IMemoryCache缓存、对象键、函数工厂)
{
如果(!cache.TryGetValue(键,输出对象结果))
{
(int-tokenExpirationSeconds,TItem-factoryResult)=
wait factory().configurewait(false);
if(令牌过期时间)秒
{
var jwt=await GetTokenFromServer();
var-tokenHasValidExpireValue=int.TryParse(jwt.ExpiresIn,out int-tokenexpireationseconds);
返回(tokenExpirationSeconds,jwt.token);
}
使用GetOrCreateAsync
除了令人困惑的行为之外,您还能从中获得什么?如果您没有始终如一地创建一个条目,调用GetOrCreateAsync
没有任何意义。@DavidL它简化了我的代码,但显然没有。正如您所演示的,您对数据有不同的期望,这意味着方法不适合您的用例。
var memoryCache = new MemoryCache(new MemoryCacheOptions());
var token = await memoryCache.GetOrCreateIfValidTimestampAsync<string>("SomeKey", async () =>
{
var jwt = await GetTokenFromServer();
var tokenHasValidExpireValue = int.TryParse(jwt.ExpiresIn, out int tokenExpirationSeconds);
return (tokenExpirationSeconds, jwt.token);
}