前言

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

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

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

Task ConfigureAwait

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

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

     private Task<List<EnglishWordInfo>> _wordsCacheDelayTask;
/// <summary>
/// 提前初始化字典
/// 注:通过InitWordInfos提前缓存数据,提升用户体验
/// </summary>
public void InitWordInfos()
{
if (_wordsCacheDelayTask == null)
{
_wordsCacheDelayTask = GetWordsTask();
}
}

使用ConfigureAwait异步获取数据

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

     /// <summary>
/// 延时获取数据
/// 注:延时获取,避免界面卡顿
/// </summary>
/// <returns></returns>
private async Task<List<EnglishWordInfo>> GetWordsTask()
{
return await Task.Run(() =>
{
return EnglishDictService.Instance.GetWords();
}).ConfigureAwait(false);
}

添加封装数据延迟任务

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

     /// <summary>
/// 获取数据延迟任务
/// 注:如果没有提前延迟任务,则重新获取数据
/// </summary>
public Task<List<EnglishWordInfo>> WordsCacheDelayTask
{
set => _wordsCacheDelayTask = value;
get
{
if (_wordsCacheDelayTask == null)
{
_wordsCacheDelayTask = GetWordsTask();
} return _wordsCacheDelayTask;
}
}

获取缓存数据

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

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

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

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

参考列表:

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

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

最新文章

  1. SpringMVC入门案例及请求流程图(关于处理器或视图解析器或处理器映射器等的初步配置)
  2. IsPostBack--Asp.net
  3. highcharts图表中级入门之xAxis label:X(横)坐标刻度值过长截断多行(换行)显示问题说明
  4. 介绍开源的.net通信框架NetworkComms框架 源码分析(十三)ThreadSafeStream
  5. delphi Components[i]清除所有edit控件中的内容
  6. 华为oj 统计字符串不同字符
  7. [汇编学习笔记][第十章 CALL和RET指令]
  8. SqlServer数据库存储过程的使用
  9. (ArcGIS API For Silverlight )QueryTask 跨层查询,和监控完整的查询!
  10. jvm中的垃圾回收器
  11. excel中的数据导出为properties和map的方法
  12. Asp.net Core 2.1新功能Generic Host(通用主机),了解一下
  13. 使用Fiddle抓取IOS手机
  14. hdu 1024 Max Sum Plus Plus(m段最大和)
  15. REST API 调用 方法
  16. C语言第七讲,函数入门.
  17. dp 动态规划 之C - Apple Catching 简单基础
  18. php的serialize()函数和unserialize()函数
  19. LINK : fatal error LNK1158: 无法运行“rc.exe”解决办法 and Visual Studio 2017 下载安装
  20. Educational Codeforces Round 10 C. Foe Pairs 水题

热门文章

  1. uiautomator——简单的将自动化测试与截图对比相结合使用的小例子!
  2. 如何使用命令行编译和运行java文件
  3. 函数strlen()和sizeof的区别
  4. 基于Unity的AR开发初探:第一个AR应用程序
  5. 简单工厂模式(Simple Factory Pattern)
  6. Django Admin管理入门
  7. 文本输入框input text输入字母自动转大写
  8. Accesss数据库的DBhelper类(带分页)
  9. 数据库 【redis】 命令大全
  10. 免费申请使用IBM Cloud Lite(轻量套餐) 续