/// <summary> /// 异步的,尝试获取指定缓存键的对象,如果没有则使用函数添加对象到缓存中。 /// </summary> /// <typeparam name="T">缓存对象的类型。</typeparam> /// <param name="cacheKey">用于引用对象的缓存键。</param> /// <param name="valueCreator">用于添加缓存对象的函数。</param> /// <param name="expiration">判断对象过期的对象。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns></returns> public async Task <T> TryGetAsync <T>(string cacheKey, Func <Task <T> > valueCreator, Func <ICacheItemExpiration> expiration = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); cacheKey = ServiceProvider.GetCacheKey(cacheKey); var client = GetConnection(cacheKey); try { async Task <CheckCache <T> > GetCacheValue() { if (await client.ExistsAsync(cacheKey)) { var redisValue = await client.GetAsync(cacheKey); if (!string.IsNullOrEmpty(redisValue)) { await HandleSlidingTimeAsync(client, cacheKey); return(CheckCache <T> .Result(Deserialize <T>(redisValue))); } } return(CheckCache <T> .Null()); } var ck = await GetCacheValue(); if (ck.HasValue) { return(ck.Value); } return(await RedisHelper.LockAsync(client, GetLockToken(cacheKey), Setting.LockTimeout, async() => { var ck1 = await GetCacheValue(); if (ck1.HasValue) { return ck1.Value; } var expiry = GetExpirationTime(expiration); var value = await valueCreator(); await client.SetAsync(cacheKey, Serialize(value), expiry == null ? -1 : (int)expiry.Value.TotalSeconds); return value; })); } catch (IOException exp) { if (Setting.IgnoreException) { Tracer.Error($"RedisCache TryGetValue throw exception:\n{exp.Output()}"); return(await valueCreator()); } throw exp; } }
/// <summary> /// 尝试获取指定缓存键的对象,如果没有则使用函数添加对象到缓存中。 /// </summary> /// <typeparam name="T">缓存对象的类型。</typeparam> /// <param name="cacheKey">用于引用对象的缓存键。</param> /// <param name="valueCreator">用于添加缓存对象的函数。</param> /// <param name="expiration">判断对象过期的对象。</param> /// <returns></returns> public T TryGet <T>(string cacheKey, Func <T> valueCreator, Func <ICacheItemExpiration> expiration = null) { cacheKey = ServiceProvider.GetCacheKey(cacheKey); var client = GetConnection(cacheKey); try { CheckCache <T> GetCacheValue() { if (client.Exists(cacheKey)) { var redisValue = client.Get(cacheKey); if (!string.IsNullOrEmpty(redisValue)) { HandleSlidingTime(client, cacheKey); return(CheckCache <T> .Result(Deserialize <T>(redisValue))); } } return(CheckCache <T> .Null()); } var ck = GetCacheValue(); if (ck.HasValue) { return(ck.Value); } return(RedisHelper.Lock(client, GetLockToken(cacheKey), Setting.LockTimeout, () => { var ck1 = GetCacheValue(); if (ck1.HasValue) { return ck1.Value; } var expiry = GetExpirationTime(expiration); var value = valueCreator(); client.Set(cacheKey, base.Serialize(value), expiry == null ? -1 : (int)expiry.Value.TotalSeconds); return value; })); } catch (IOException exp) { if (Setting.IgnoreException) { Tracer.Error($"RedisCache TryGetValue throw exception:\n{exp.Output()}"); return(valueCreator()); } throw exp; } }
/// <summary> /// 异步的,尝试从集合中获取指定 <paramref name="key"/> 的数据,如果没有则使用函数添加对象到集合中。 /// </summary> /// <param name="key">标识数据的 key。</param> /// <param name="valueCreator">用于添加缓存对象的函数。</param> /// <param name="expiration">判断对象过期的对象。</param> /// <param name="cancellationToken">取消操作的通知。</param> /// <returns></returns> public async Task <TValue> TryGetAsync(TKey key, Func <Task <TValue> > valueCreator, Func <ICacheItemExpiration> expiration = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); TryReInitialize(); var sKey = key.ToString(); async Task <CheckCache <TValue> > GetCacheValue() { if (await _client.HExistsAsync(_cacheKey, sKey)) { var content = await _client.HGetAsync(_cacheKey, sKey); var item = _deserialize(content); if (!item.HasExpired()) { return(CheckCache <TValue> .Result(item.Value)); } } return(CheckCache <TValue> .Null()); } var ck = await GetCacheValue(); if (ck.HasValue) { return(ck.Value); } return(await RedisHelper.LockAsync(_client, string.Concat(_cacheKey, ":", sKey), _setting.LockTimeout, async() => { var ck1 = await GetCacheValue(); if (ck1.HasValue) { return ck1.Value; } var value = await valueCreator(); var content = _serialize(new RedisCacheItem <TValue>(value, expiration == null ? NeverExpired.Instance : expiration())); await _client.HSetAsync(_cacheKey, sKey, content); return value; })); }
/// <summary> /// 尝试从集合中获取指定 <paramref name="key"/> 的数据,如果没有则使用函数添加对象到集合中。 /// </summary> /// <param name="key">标识数据的 key。</param> /// <param name="valueCreator">用于添加缓存对象的函数。</param> /// <param name="expiration">判断对象过期的对象。</param> /// <returns></returns> public TValue TryGet(TKey key, Func <TValue> valueCreator, Func <ICacheItemExpiration> expiration = null) { TryReInitialize(); var sKey = key.ToString(); CheckCache <TValue> GetCacheValue() { if (_client.HExists(_cacheKey, sKey)) { var content = _client.HGet(_cacheKey, sKey); var item = _deserialize(content); if (!item.HasExpired()) { return(CheckCache <TValue> .Result(item.Value)); } } return(CheckCache <TValue> .Null()); } var ck = GetCacheValue(); if (ck.HasValue) { return(ck.Value); } return(RedisHelper.Lock(_client, string.Concat(_cacheKey, ":", sKey), _setting.LockTimeout, () => { var ck1 = GetCacheValue(); if (ck1.HasValue) { return ck1.Value; } var value = valueCreator(); var content = _serialize(new RedisCacheItem <TValue>(value, expiration == null ? NeverExpired.Instance : expiration())); _client.HSet(_cacheKey, sKey, content); return value; })); }