You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为C#项目Redis缓存的Get<T>方法重载添加过期时间

为Redis缓存提供器实现带超时的Get方法重载

我来帮你完成给Redis缓存添加过期功能的需求——通过重载Get<T>系列方法,让它支持接收超时值。下面是修改后的完整代码,关键改动处我都做了标注:

public async Task<T> GetAsync<T>(string key) 
{ 
    return await _cacheClient.Db0.GetAsync<T>(key).ConfigureAwait(false); 
}

/// <summary>
/// Fetch item from cache
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <returns>Cached item</returns>
public T Get<T>(string key) 
{ 
    return AsyncHelper.RunSync(() => _cacheClient.Db0.GetAsync<T>(key)); 
}

/// <summary>
/// Fetch from cache, else execute operation and cache
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <param name="method">Method to execute</param>
/// <param name="args">Method args</param>
/// <returns></returns>
public async Task<T> GetAsync<T>(string key, Delegate method, params object[] args) 
{ 
    T result = default(T); 
    try 
    { 
        if (await _cacheClient.Db0.ExistsAsync(key).ConfigureAwait(false)) 
        { 
            return await _cacheClient.Db0.GetAsync<T>(key).ConfigureAwait(false); 
        } 
        else 
        { 
            result = ExecMethod<T>(method, args); 
            await _cacheClient.Db0.AddAsync(key, result).ConfigureAwait(false); 
        } 
    } 
    catch (Exception ex) 
    { 
        _logHandler.LogError($"Error fetching cache for key:{key}", ex); 
        result = ExecMethod<T>(method, args); 
    } 
    return result; 
}

/// <summary>
/// Fetch from cache, else execute operation and cache
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <param name="method">Method to execute</param>
/// <param name="args">Method args</param>
/// <returns></returns>
public T Get<T>(string key, Delegate method, params object[] args) 
{ 
    T result = default(T); 
    try 
    { 
        if (AsyncHelper.RunSync(() => _cacheClient.Db0.ExistsAsync(key))) 
        { 
            result = AsyncHelper.RunSync(() => _cacheClient.Db0.GetAsync<T>(key)); 
        } 
        else 
        { 
            result = ExecMethod<T>(method, args); 
            var added = AsyncHelper.RunSync(() => _cacheClient.Db0.AddAsync(key, result)); 
        } 
    } 
    catch (Exception ex) 
    { 
        _logHandler.LogError($"Error fetching cache for key:{key}", ex); 
        result = ExecMethod<T>(method, args); 
    } 
    return result; 
}

// -------------------------- 新增带超时的重载方法 --------------------------

/// <summary>
/// Fetch from cache, else execute operation and cache with specified expiry
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <param name="method">Method to execute</param>
/// <param name="expiry">Cache expiration time</param>
/// <param name="args">Method args</param>
/// <returns></returns>
public async Task<T> GetAsync<T>(string key, Delegate method, TimeSpan expiry, params object[] args)
{
    T result = default(T);
    try
    {
        if (await _cacheClient.Db0.ExistsAsync(key).ConfigureAwait(false))
        {
            return await _cacheClient.Db0.GetAsync<T>(key).ConfigureAwait(false);
        }
        else
        {
            result = ExecMethod<T>(method, args);
            // 关键改动:将过期时间传入AddAsync,实现缓存自动过期
            await _cacheClient.Db0.AddAsync(key, result, expiry).ConfigureAwait(false);
        }
    }
    catch (Exception ex)
    {
        _logHandler.LogError($"Error fetching cache for key:{key}", ex);
        result = ExecMethod<T>(method, args);
    }
    return result;
}

/// <summary>
/// Fetch from cache, else execute operation and cache with specified expiry
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <param name="method">Method to execute</param>
/// <param name="expiry">Cache expiration time</param>
/// <param name="args">Method args</param>
/// <returns></returns>
public T Get<T>(string key, Delegate method, TimeSpan expiry, params object[] args)
{
    T result = default(T);
    try
    {
        if (AsyncHelper.RunSync(() => _cacheClient.Db0.ExistsAsync(key)))
        {
            result = AsyncHelper.RunSync(() => _cacheClient.Db0.GetAsync<T>(key));
        }
        else
        {
            result = ExecMethod<T>(method, args);
            // 关键改动:同步方法中同样传入过期时间
            var added = AsyncHelper.RunSync(() => _cacheClient.Db0.AddAsync(key, result, expiry));
        }
    }
    catch (Exception ex)
    {
        _logHandler.LogError($"Error fetching cache for key:{key}", ex);
        result = ExecMethod<T>(method, args);
    }
    return result;
}

// 可选:如果需要Redis操作本身的超时控制(而非缓存数据过期),可以添加以下重载
/// <summary>
/// Fetch item from cache with operation timeout
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <param name="timeout">Operation timeout limit</param>
/// <returns>Cached item</returns>
public async Task<T> GetAsync<T>(string key, TimeSpan timeout)
{
    using var cts = new CancellationTokenSource(timeout);
    return await _cacheClient.Db0.GetAsync<T>(key, cts.Token).ConfigureAwait(false);
}

/// <summary>
/// Fetch item from cache with operation timeout
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="key">Key identifier in cache</param>
/// <param name="timeout">Operation timeout limit</param>
/// <returns>Cached item</returns>
public T Get<T>(string key, TimeSpan timeout)
{
    return AsyncHelper.RunSync(() => GetAsync<T>(key, timeout));
}

核心改动说明:

  1. 缓存过期支持:重点给「缓存不存在时执行方法并缓存」的GetAsync和Get方法添加了TimeSpan expiry参数,在调用AddAsync时传入该参数,让Redis自动管理缓存的过期时间。
  2. 操作超时控制(可选):如果你的需求是限制Redis操作本身的耗时(比如获取缓存时最多等1秒),可以使用新增的直接获取重载,通过CancellationTokenSource实现超时控制。
  3. 性能优化:在异步方法中保留了ConfigureAwait(false),避免不必要的上下文切换,提升异步代码性能。
  4. 兼容性:原有方法完全保留,新增的重载不会影响现有业务代码的调用。

内容的提问来源于stack exchange,提问作者Mohammed Ismail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:22:37