【问题标题】:What's the best way to Asyncronously load properties in C# [closed]在 C# 中异步加载属性的最佳方法是什么 [关闭]
【发布时间】:2021-04-28 01:29:45
【问题描述】:

我正在使用 c# .net core 5 Blazer WebService。

我有一项服务,其中包含事物列表作为属性。

public class Service : IService
{
    public HashSet<Thing> Things {get; set;}
}

现在我想从磁盘加载事物,所以我将它们私下缓存在服务中

public class Service : IService
{
    private HashSet<Thing> _things
    public HashSet<Thing> Things => _things : LoadThings();
}

但是 LoadThings() 访问磁盘,所以我希望该 IO 异步运行并等待它。但是现在 LoadThings() 需要异步,我做不到:

public class Service : IService
{
    private HashSet<Thing> _things
    public HashSet<Thing> Things => _things : await LoadThings();
}

我明白为什么了;异步链丢失。

所以我的问题是:如果 _things 为空,那么获取 _things 但等待异步 IO 的最佳方法是什么?

【问题讨论】:

  • 没有异步属性。将属性替换为返回缓存数据或检索新数据的方法
  • 如果你想延迟初始化数据而不是实际缓存它们过期你可以检查AsyncLazy
  • But LoadThings() accesses the disk so I want that IO to run asynchronously 取决于你在做什么(在LoadThings),记住这可能不是要走的路,仍然可以同步运行;只是一个想法。

标签: c# .net-core async-await


【解决方案1】:

当您说“缓存”时,我假设您指的是仅加载和重用它们的东西,而不是过期的“缓存”。这似乎与您现有的代码相匹配。

在这种情况下,您可以这样做:

    public class Service : IService
    {
        private Lazy<Task<HashSet<Thing>>> _things;

        public Service()
        {
            _things = new Lazy<Task<HashSet<Thing>>>(LoadThings);
        }

        public async Task MethodThatNeedsThings()
        {
            var things = await _things.Value;
            // Now you've got things and you can use them.
        }

        private async Task<HashSet<Thing>> LoadThings()
        {
            // This method asynchronously loads your things.
        }
    }

这些东西在您第一次需要它们时被异步加载,之后它们在后续调用中可用。

【讨论】:

  • 我的印象是在构造函数中做这样复杂的事情通常是个坏主意。这对我来说看起来不错,但这里发生的是 IO 抛出错误?
  • @Tod 构造函数中没有发生复杂的事情。 LoadThings 在首次访问 _things.Value 时会延迟评估,因此在调用 MethodThatNeedsThings 时会抛出任何异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-06
  • 2020-03-14
相关资源
最近更新 更多