我设置了 Blazor 服务器应用程序,在其中缓存登录用户的
AppUser
对象。这是一个相当繁重的数据库读取操作,有 11 个查询(使用 SplitQueries)。但一旦我拥有了它,它就会为我提供每个页面所需的 90% 的内容。我认为这是一个不错的权衡。
问题是,对于大多数页面,我有几个组件需要这个对象。所以他们所有人,在他们的
OnInitializedAsync()
中,调用缓存这个对象的服务。因此对该对象有 4 个调用。所有 4 个都发现它不在缓存中,并从数据库中读取它,然后所有 4 个将其放入缓存中。显示第一页的 ½ 秒延迟变成了 2 秒延迟。
我该如何解决这个问题?我想出的最好的办法是我有一个待处理查询的字典和一个互斥体或事件。如果待处理字典中存在对
AppUser
的请求,则请求会在互斥体/事件上阻塞,并在释放时开始在缓存中查找,然后在需要时读取(不应该如此)。
还有其他方法吗?如果挂起的互斥体是执行此操作的最佳方法,那么我需要注意什么吗?
您应该能够使用范围服务执行类似的操作:
public class MyService
{
private Task? _loadingTask;
// Can kick off the load in the Ctor if you wish
public MyService()
{
_loadingTask = this.Initialize();
}
public Task LoadData()
{
// If _loadingTask is null then we need to start the loading process
if (_loadingTask == null)
{
_loadingTask = this.Initialize();
return _loadingTask;
}
if (_loadingTask.IsFaulted)
{
// Add code to deal with exections
}
return _loadingTask;
}
public async Task GetData()
{
await LoadData();
// return whatever data you want;
}
private async Task Initialize()
{
await Task.Delay(1000);
}
}