【发布时间】:2016-01-30 00:14:45
【问题描述】:
我的应用程序有以下缓存实现:
public static class Keys
{
public const string CacheKey = "cachekey";
}
public interface ICache
{
string QueryCachedData(string param);
}
应用程序在 Global.asax 中启动时加载数据
//Global.asax
protected void Application_Start(object sender, EventArgs e)
{
//instantiates the repository
HttpContext.Current.Application[Keys.CacheKey] = repository.getDataView();
}
实现从 HttpContext.Current 恢复数据
public class Cache : ICache
{
private Cache() { }
private static Cache _instance = null;
public static Cache GetInstance()
{
if (_instance == null)
_instance = new Cache();
return _instance;
}
private System.Data.DataView GetCachedData()
{
if (HttpContext.Current.Application[Keys.CacheKey] == null)
{
//instantiates the repository
HttpContext.Current.Application[Keys.CacheKey] = repository.getDataView();
}
return HttpContext.Current.Application[Keys.CacheKey] as System.Data.DataView;
}
private readonly Object _lock = new Object();
public string QueryCachedData(string param)
{
lock (_lock)
{
var data = GetCachedData();
//Execute query
return result;
}
}
}
在某些时候,我需要使用缓存使用以下类的第三方 Web 服务...
public class ThirdPartyWebserviceConsumer
{
ICache _cache;
int _provider;
public ThirdPartyWebserviceConsumer(int provider, ICache cache)
{
_cache = cache;
_provider = provider;
}
public result DoSomething()
{
var info = _cache.QueryCachedData(param);
}
}
...使用多线程:
public List<Result> Foo(ICache cache, List<int> collectionOfProviders)
{
List<Result> results = new List<Result>();
List<Task> taskList = new List<Task>();
foreach (var provider in collectionOfProviders)
{
var task = new Task<Result>(() => new ThirdPartyWebserviceConsumer(provider, cache).DoSomething());
task.Start();
task.ContinueWith(task =>
{
results.Add(task.Result);
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
return results;
}
我的问题是 HttpContext.Current.Application 在 thead 上下文中为空。 我有什么选择?有一些形式可以在线程中访问 HttpContext 吗?或者可能是其他类型的可以在线程之间共享的缓存?
【问题讨论】:
-
您似乎没有在多线程代码块中访问 HttpContext.Current。您能否提供更多详细信息,例如异常的堆栈跟踪?
-
它会抛出未设置到 GetCachedData 中对象实例的引用,因为 HttpContext.Current 为空。我已经编辑了问题并添加了task.start()
-
还有一个问题,“Foo”方法被放到了一个不引用System.Web的类库中,我不想加了。所以我不能这样做: var context = HttpContext.Current; ... HttpContext.Current = 上下文;
-
您为什么不只是(正如 Eric J. 在他的回答中建议的那样)将缓存的数据传递给后台线程?更好的是,由于您的缓存中只有一个项目,您还可以将其设为静态变量或将其放入 Cache 类中的静态 Dictionary 中,并且可以删除 HttpContext 依赖项。这将使您的 Cache 类也可以在桌面应用程序中重用。
标签: c# asp.net multithreading caching httpcontext