我在我的一个基类中找到了以下代码,它完美地运行(请参阅注释):
private static Dictionary<string, TItem> _cache;
protected Dictionary<string, TItem> Cache
{
get
{
if (_cache == null)
{
// Instead of FillCacheAsync().Wait(); I now do the following:
var reset = new AutoResetEvent(false);
Task.Run(
async () =>
{
await FillCacheAsync();
reset.Set();
});
reset.WaitOne();
}
return _cache;
}
}
private async Task FillCacheAsync()
{
_cache = new Dictionary<string, TItem>();
await InternalCacheFillAsync();
}
// This is not part of the question.
protected abstract Task InternalCacheFillAsync();
对于懒惰属性不能标记为async
的问题,这是一个很好的解决方案吗?即使使用ConfigureAwait(false)
,我也遇到了很多问题。
答案 0 :(得分:4)
Stephen Cleary在他的博客中介绍了async properties的确切主题。
他提出了一种简洁的方法来满足您对缓存值属性的需求,该属性将使用AsyncLazy<T>
中的AsyncEx library以异步方式缓存,这将节省您使用AutoResetEvent的需要并将简化您的代码。
具有缓存属性的类的简单示例:
public class SomeClass
{
static SomeClass()
{
Cache = new AsyncLazy<Dictionary<string, TItem>>(GetCacheAsync);
}
public static AsyncLazy<Dictionary<string, TItem>> Cache { get; }
private static Task<Dictionary<string, TItem>> GetCacheAsync()
{
....
}
}.
访问缓存属性的值:
Dictionary<string, TItem> value = await SomeClass.Cache;