c# - 使用 DI 为线程范围缓存昂贵的对象,而不阻塞(异步)
问题描述
我有一个昂贵的“当前用户”对象,我想在请求期间缓存它。为此,我使用 asp.net 核心中的内置 DI,ICurrentUser
在请求时创建对象。它看起来像这样:
public class CurrentUserCache : ICurrentUser
{
public CurrentUserCache(IHttpContextAccessor httpContextAccessor, UserManager userManager)
{
var httpContextAccessor1 = httpContextAccessor;
_user = new Lazy<User>(() => httpContextAccessor1.HttpContext.User != null ? userManager.GetUserAsync(httpContextAccessor1.HttpContext.User).Result : null);
}
private Lazy<User> _user;
public User User {
get => _user.Value;
set {}
}
}
它使用Lazy
对象来延迟对象的检索,因为某些控制器操作可能不需要使用它。
我的问题是 - 懒得获取用户的代码里面的代码是阻塞的(.Result
)。我不想这样做,因为它非常昂贵。
我不知道如何使这段代码异步。我可以创建一个Lazy<Task<user>>
来获取用户,但是我不能await
在我的用户属性中这样做,因为它是一个属性并且属性不能是异步的。
那么 - 我怎样才能把这段代码变成适合异步的东西呢?
谢谢!
解决方案
将属性变成等待函数
public class CurrentUserCache : ICurrentUser {
public CurrentUserCache(IHttpContextAccessor httpContextAccessor, UserManager userManager) {
_user = new Lazy<Task<User>>(() =>
userManager.GetUserAsync(httpContextAccessor.HttpContext.User)
);
}
private Lazy<Task<User>> _user;
public Task<User> GetUserAsync() {
return _user.Value;
}
}