Iss*_*ram 7 .net c# asynchronous memorycache .net-core
我正在使用 来IMemoryCache缓存从身份服务器检索到的令牌。
过去我使用过库GetOrCreateAsync中提供的扩展方法Microsoft.Extensions.Caching.Abstractions。这非常有帮助,因为我可以同时定义函数和到期日期。
但是,使用令牌时,在请求完成之前我不会知道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;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,当我尝试设置 no time 过期时,会引发异常TimeSpan.FromSeconds(0)。
除了分别调用Get和Set方法之外,还有其他方法可以解决这个问题吗?如果可能的话我想使用该GetOrCreateAsync方法。
您实际上无法使用当前扩展来完成此操作,因为它始终会在调用工厂方法之前创建一个条目。也就是说,您可以以与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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以以非常类似的方式调用扩展方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1929 次 |
| 最近记录: |