using System;
using System.Threading.Tasks;
namespace LiveForum.Code.SystemCache
{
///
/// 字段缓存服务基类(提供通用的字段缓存实现)
///
/// 缓存值类型
public abstract class FieldCacheServiceBase : IFieldCacheService
{
private TValue _cachedValue;
private readonly object _cacheLock = new object();
///
/// 加载数据的方法(子类需要实现)
///
/// 数据值
protected abstract Task LoadDataAsync();
///
/// 获取缓存值(如果缓存不存在,会调用加载方法)
///
public virtual async Task 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;
}
///
/// 清除实例字段缓存
///
public virtual void ClearCache()
{
lock (_cacheLock)
{
_cachedValue = default(TValue);
}
}
///
/// 刷新缓存(清除并重新加载)
///
public virtual async Task RefreshCacheAsync()
{
ClearCache();
await GetAsync();
}
///
/// 判断值是否为空(处理值类型和引用类型)
///
private bool IsNullValue(TValue value)
{
if (value == null)
return true;
// 对于字符串,检查是否为空
if (value is string str)
return string.IsNullOrWhiteSpace(str);
return false;
}
}
}