【发布时间】:2018-08-01 07:53:34
【问题描述】:
我有以下几点:
public class User
{
private readonly Lazy<Task<List<ReminderDb>>> _reminders;
public SmsUserDb()
{
// Get _reminderReader from IoC
_reminders = new Lazy<Task<List<ReminderDb>>>(async () => (List<ReminderDb>)await _reminderReader.Get(UserId));
}
public string UserId { get; set; }
public Task<List<ReminderDb>> Reminders => _reminders.Value;
}
当我像这样实例化一个对象时:
var n = new SmsUserDb {UserId = "123456"};
var rems = await n.Reminders;
此代码有效,我看到 n.Reminders ="Waiting for activation" 直到我点击 await n.Reminders 行。
但是,当我像这样从缓存中查询此用户对象时:
var n1 = await _userReader.GetUserFromCache("+17084556675"); // return SmsUserDb
var n2 = await n1.Reminders;
当它点击 GetUserFromCache() 时,它会立即调用 _reminderReader.Get(UserId) 再次调用缓存以获取提醒。然后它只是超时。所以 Lazy 不起作用,很可能会导致死锁。
public async Task<SmsUserDb> GetUserFromCache(string phoneNumber)
{
var hash = CachedObjectType.smsuser.ToString();
var fieldKey = string.Format($"{CachedObjectType.smsuser.ToString()}:user-{phoneNumber}");
var result = await _cacheUserService.GetHashedAsync(hash, fieldKey);
return result;
}
private async Task<List<ReminderDb>> GetRemindersFromCache(string userId)
{
var hash = CachedObjectType.smsreminder.ToString();
var fieldKey = string.Format($"{CachedObjectType.smsreminder.ToString()}:user-{userId}");
var result = await _cacheService.GetHashedAsync(hash, fieldKey);
return result ?? new List<ReminderDb>();
}
可能是什么问题?
【问题讨论】:
-
那么
GetUserFromCache()是做什么的? -
简单地从缓存中获取用户(我已经添加了那个方法)。但我的意图是,在我执行 await user.Reminders; 的某个地方之前,不会调用 Reminders 属性。此外,如果我从 SmsUserDb 对象中删除 Reminder 属性它工作正常。好像是 Lazy
导致了问题。 -
问题不清楚,代码不完整。这个 _reminderReader.Get(UserId) 到底是什么?
-
_reminderReader.Get(userId) 简单地调用这个 => GetRemindersFromCache()
-
这在我的测试代码中一切正常。该错误必须与您缓存数据的方式有关。也许是序列化/反序列化?您需要发布一个完整的可编译示例,因为您实际发布的所有代码都可以正常工作。
标签: c# asp.net .net lazy-initialization