live-forum/server/webapi/LiveForum/LiveForum.Code/SystemCache/FieldCacheServiceBase.cs
2026-03-24 11:27:37 +08:00

87 lines
2.4 KiB
C#

using System;
using System.Threading.Tasks;
namespace LiveForum.Code.SystemCache
{
/// <summary>
/// 字段缓存服务基类(提供通用的字段缓存实现)
/// </summary>
/// <typeparam name="TValue">缓存值类型</typeparam>
public abstract class FieldCacheServiceBase<TValue> : IFieldCacheService<TValue>
{
private TValue _cachedValue;
private readonly object _cacheLock = new object();
/// <summary>
/// 加载数据的方法(子类需要实现)
/// </summary>
/// <returns>数据值</returns>
protected abstract Task<TValue> LoadDataAsync();
/// <summary>
/// 获取缓存值(如果缓存不存在,会调用加载方法)
/// </summary>
public virtual async Task<TValue> GetAsync()
{
// 如果缓存存在,直接返回(同一请求内共享)
if (_cachedValue != null && !IsNullValue(_cachedValue))
{
return _cachedValue;
}
// 首次调用,加载数据并缓存
// 注意:这里先加载数据,再锁定设置缓存,避免在 lock 内执行异步操作
var loadedValue = await LoadDataAsync();
lock (_cacheLock)
{
// 双重检查,避免并发加载
if (_cachedValue != null && !IsNullValue(_cachedValue))
{
return _cachedValue;
}
_cachedValue = loadedValue;
}
return _cachedValue;
}
/// <summary>
/// 清除实例字段缓存
/// </summary>
public virtual void ClearCache()
{
lock (_cacheLock)
{
_cachedValue = default(TValue);
}
}
/// <summary>
/// 刷新缓存(清除并重新加载)
/// </summary>
public virtual async Task RefreshCacheAsync()
{
ClearCache();
await GetAsync();
}
/// <summary>
/// 判断值是否为空(处理值类型和引用类型)
/// </summary>
private bool IsNullValue(TValue value)
{
if (value == null)
return true;
// 对于字符串,检查是否为空
if (value is string str)
return string.IsNullOrWhiteSpace(str);
return false;
}
}
}