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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM