前言
假設有如下代碼,功能是首先從緩存獲取數據,如果沒有命中緩存,則直接從數據庫獲取:
var?data?=?await?GetFromCache();
if?(data?is?null)
{data?=?await?GetFromDB();
}
對于獲取緩存數據,我們需要限制一下GetFromCache
方法的執行時間,比如 3 秒,超過這個時間,可以認為拿不到緩存數據,應該直接從數據庫取值。
那么,能否在不修改GetFromCache
方法的前提下,讓?Task?超時時自動結束執行?
思路
雖然不能把普通Task
變成一個可超時的?Task
,但是我們可以定時檢查任務狀態。如果到達超時時間,原始 Task
仍未執行完成,則跳過該 Task
,繼續執行后續代碼。
實現
為 Task
創建擴展方法:
public?static?async?Task<T>?Timeout<T>(this?Task<T>?task,?int?milliseconds)
{var?now?=?DateTime.Now.AddMilliseconds(milliseconds);while?(DateTime.Now?<?now){if?(task.IsCompleted){return?await?task;}await?Task.Delay(100);}return?default(T);
}
使用也很簡單:
var?data?=?await?GetFromCache().Timeout(1000);if?(data?is?null)
{data?=?await?GetFromDB();
}
需要注意的是,我們僅僅是不再 await
原始 Task
執行完成,并不代表真正地終止了它的運行,原始 Task
還是會繼續執行,只是我們不再關心它的返回結果而已。
結論
今天,我們通過實現 Timeout
擴展方法,為異步任務添加了超時功能。
添加微信號【MyIO666】,邀你加入技術交流群