前言
在我們應用程序中,如果有較大的數據需要從數據庫或者本地讀取,且是一次性的話,可以提前獲取數據並緩存在內存中。
一般處理方法:利用應用程序啟動到用戶使用功能這一段時間,提前加載數據。
問題來了,因數據大小的不固定性,提前加載的速度有快有慢,如果保證不會重復讀取數據庫、只返回一次結果呢?
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;
參考列表: