我正在尝试增强in proc MVC缓存以提供旧值,同时触发新线程来填充新值。
如果删除该行,则以下代码“有效”:
ThreadPool.QueueUserWorkItem(delegate
“工作”是指在刷新缓存之前阻止发出触发缓存重新加载的请求的客户端,但所有其他客户端继续加载阴影版本。
理想情况下,我希望在后台进行处理,并且触发缓存刷新的客户端使用该请求的卷影副本。当线程完成后,当他们提出将来的请求时,他们将获得新的缓存值。
我的解决方案在很大程度上依赖于Castle作为DI框架。我相信我遇到的问题是与Castle中的LifeStyles有关。错误消息是:
HttpContext.Current为null。 PerWebRequestLifestyle只能在ASP.Net
中使用在尝试解析所需组件时,异常发生在长时间运行进程( getCacheItem())的内部深处。
我的缓存方法如下:
public T GetShadow<T>(string key, Func<T> getCacheItem, int timeOut)
{
if (Exists(key))
{
_log.Info("Shadow: Returning item from Cache: " + key);
return (T)HttpContext.Current.Cache[key];
}
var shadowKey = key + "-shadow";
if (Monitor.TryEnter(GetKeyLock(key)))
{
ThreadPool.QueueUserWorkItem(delegate
{
try
{
var item = getCacheItem(); // Long running query
// Replace the cache entry
HttpRuntime.Cache.Insert(key, item, null,
DateTime.UtcNow.AddMinutes(
timeOut), Cache.NoSlidingExpiration);
// And add its shadow for subsequent updates
HttpRuntime.Cache.Insert(shadowKey, item, null,
DateTime.UtcNow.AddMinutes(timeOut * 2), Cache.NoSlidingExpiration);
}
finally
{
Monitor.Exit(GetKeyLock(key));
}
});
}
while (!Exists(shadowKey))
{
Thread.Sleep(500);
}
return (T)HttpContext.Current.Cache[shadowKey];
}
所以我的问题是,我是否在MVC3中正确创建了线程?
在这种情况下是否有更好的方法来启动线程,这会导致Windsor因PWR生活方式而抛出异常?
答案 0 :(得分:3)
所以我的问题是,我是否在MVC3中正确创建了线程?
不,您在ASP.NET应用程序的后台线程中使用HttpContext.Current
。你的问题与Windsor和ASP.NET MVC无关。这只是你不能做的事情,因为后台线程(顾名思义)可以在任何用户HTTP上下文之外的后台运行。因此,尝试在这样的线程中访问此上下文没有任何意义。
由于新的MemoryCache类设计为独立于ASP.NET使用,因此可以使用.NET 4.0中的新缓存功能。