【发布时间】:2017-03-12 17:10:21
【问题描述】:
我有同步 HttpHandler。我想缓存 HttpClient.GetAsync 的结果并在我的 HttpHandler 中使用它。我是这样做的:
public static class CacheFacade
{
private static Cache Cache => HttpRuntime.Cache;
private const string CacheKey = "asynccache";
private static readonly object _lockObject = new object();
public static string GetStringFromCache()
{
if (Cache[CacheKey] == null)
{
lock(_lockObject)
{
if (Cache[CacheKey] == null)
{
InitCache();
}
}
//fallback here; I can use data from some synchronous source
return "init cache" + " - " + Thread.CurrentThread.ManagedThreadId;
}
var task = (Task<string>) Cache[CacheKey];
if (!task.IsCompleted)
{
//and fallback here too
return task.Status + " - " + DateTime.UtcNow + " - " + Thread.CurrentThread.ManagedThreadId;
}
return task.Result;
}
private static void InitCache()
{
var task = Task.Run(GetDataAsync);
Cache.Insert(CacheKey, task, null, DateTime.Now.Add(TimeSpan.FromSeconds(10)),
Cache.NoSlidingExpiration);
}
private static async Task<string> GetDataAsync()
{
using (var httpClient = new HttpClient())
{
await Task.Delay(TimeSpan.FromSeconds(2));
var res = await httpClient.GetAsync("http://www.google.com");
return res.StatusCode + " - " + DateTime.UtcNow + " - " + Thread.CurrentThread.ManagedThreadId;
}
}
}
它有效。这种方法有什么缺点吗?
更新:根据https://en.wikipedia.org/wiki/Double-checked_locking 添加带有双重检查的锁。
【问题讨论】:
-
有什么具体问题吗?
标签: asp.net caching async-await task