zoukankan      html  css  js  c++  java
  • C# 提前异步加载数据

    前言

    在我们应用程序中,如果有较大的数据需要从数据库或者本地读取,且是一次性的话,可以提前获取数据并缓存在内存中。

    一般处理方法:利用应用程序启动到用户使用功能这一段时间,提前加载数据。

    问题来了,因数据大小的不固定性,提前加载的速度有快有慢,如果保证不会重复读取数据库、只返回一次结果呢?

    Task ConfigureAwait

    使用ConfigureAwait可以解决以上问题。详情如下:

     程序启动后,在相应的事件中,调用初始化方法

     1     private Task<List<EnglishWordInfo>> _wordsCacheDelayTask;
     2     /// <summary>
     3     /// 提前初始化字典
     4     /// 注:通过InitWordInfos提前缓存数据,提升用户体验
     5     /// </summary>
     6     public void InitWordInfos()
     7     {
     8         if (_wordsCacheDelayTask == null)
     9         {
    10             _wordsCacheDelayTask = GetWordsTask();
    11         }
    12     }

    使用ConfigureAwait异步获取数据

    通过ConfigureAwait的使用,不等待结果的返回。

     1     /// <summary>
     2     /// 延时获取数据
     3     /// 注:延时获取,避免界面卡顿
     4     /// </summary>
     5     /// <returns></returns>
     6     private async Task<List<EnglishWordInfo>> GetWordsTask()
     7     {
     8         return await Task.Run(() =>
     9         {
    10             return EnglishDictService.Instance.GetWords();
    11         }).ConfigureAwait(false); 
    12     }

    添加封装数据延迟任务

    如果不是程序启动后立即加载缓存,而是程序使用期间对数据缓存的处理。可以添加如下对缓存延迟任务的封装,保证只获取一次缓存数据。

     1     /// <summary>
     2     /// 获取数据延迟任务
     3     /// 注:如果没有提前延迟任务,则重新获取数据
     4     /// </summary>
     5     public Task<List<EnglishWordInfo>> WordsCacheDelayTask
     6     {
     7         set => _wordsCacheDelayTask = value;
     8         get
     9         {
    10             if (_wordsCacheDelayTask == null)
    11             {
    12                 _wordsCacheDelayTask = GetWordsTask();
    13             }
    14 
    15             return _wordsCacheDelayTask;
    16         }
    17     }

    获取缓存数据

    通过Task.Result,获取缓存任务的结果,此缓存任务的状态可以是:

    • 执行中 -- 则会在原有进度下,继续执行并返回结果
    • 已完成 -- 则会返回原有的结果

    无论获取多少次,Result只会返回同样的结果,可以把WordsCacheDelayTask.Result看成是一个静态的缓存。

    1     /// <summary>
    2     /// 获取缓存数据
    3     /// </summary>
    4     private List<EnglishWordInfo> WordInfosCache => WordsCacheDelayTask.Result;

    参考列表:

    在编写异步方法时,使用 ConfigureAwait(false) 避免使用者死锁

    将 async/await 异步代码转换为安全的不会死锁的同步代码(使用 PushFrame)

  • 相关阅读:
    java并发编程的艺术笔记-第二章
    java并发编程的艺术笔记-第一章
    Class字节码的加载
    Maven学习笔记(1)
    深入分析java web技术内幕读书笔记-第一章
    VMware虚拟机扩展内存和磁盘
    【避坑】for循环删除列表元素的注意事项--remove函数逆序删除
    虚拟机无法上网问题解决
    jmeter变量跨线程组使用--设置全局变量
    常见慢查询原因
  • 原文地址:https://www.cnblogs.com/kybs0/p/10471922.html
Copyright © 2011-2022 走看看