Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在IMemoryCache上调用扩展方法GetOrCreateAync时是否可以避免缓存?_C#_.net_.net Core_Memorycache - Fatal编程技术网

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);
}