我正在尋找一種優雅的方式來緩存我的異步操作的結果。緩存異步操作
我第一次碰到這樣的同步方法:
public String GetStuff(String url)
{
WebRequest request = WebRequest.Create(url);
using (var response = request.GetResponse())
using (var sr = new StreamReader(response.GetResponseStream()))
return sr.ReadToEnd();
}
然後我做了異步:
public async Task<String> GetStuffAsync(String url)
{
WebRequest request = WebRequest.Create(url);
using (var response = await request.GetResponseAsync())
using (var sr = new StreamReader(response.GetResponseStream()))
return await sr.ReadToEndAsync();
}
於是我決定,我應該緩存的結果,所以我並不需要查詢外面那往往:
ConcurrentDictionary<String, String> _cache = new ConcurrentDictionary<String, String>();
public async Task<String> GetStuffAsync(String url)
{
return _cache.GetOrAdd(url, await GetStuffInternalAsync(url));
}
private async Task<String> GetStuffInternalAsync(String url)
{
WebRequest request = WebRequest.Create(url);
using (var response = await request.GetResponseAsync())
using (var sr = new StreamReader(response.GetResponseStream()))
return await sr.ReadToEndAsync();
}
然後,我讀了一篇文章(o看了一個視頻)關於如何cachi NG Task<T>
是更好的,因爲他們創造昂貴:
ConcurrentDictionary<String, Task<String>> _cache = new ConcurrentDictionary<String, Task<String>>();
public Task<String> GetStuffAsync(String url)
{
return _cache.GetOrAdd(url, GetStuffInternalAsync(url));
}
private async Task<String> GetStuffInternalAsync(String url)
{
WebRequest request = WebRequest.Create(url);
using (var response = await request.GetResponseAsync())
using (var sr = new StreamReader(response.GetResponseStream()))
return await sr.ReadToEndAsync();
}
而現在的問題是,如果請求失敗(例如:一個HTTP 401),高速緩存將包含一個失敗Task<String>
,我將不得不重新設置該應用程序,因爲它將不可能重新發送請求。
是否有一種優雅的方式使用ConcurrentDictionary<T1,T2>
緩存只成功的任務,仍然有原子行爲?
操作系統已經爲您緩存了HTTP請求,並且會正確地遵循HTTP語義(即不緩存401)。 –
https://stackoverflow.com/questions/31831860/async-threadsafe-get-from-memorycache –