【问题标题】:Consume HttpContext Cache with threads使用线程使用 HttpContext Cache
【发布时间】: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


【解决方案1】:

我的问题是 HttpContext.Current.Application 在 thead 上下文中为空。我有什么选择?

HttpContext.Current 绑定到处理当前请求的托管线程。

如果您需要来自当前上下文的数据用于另一个线程,则需要先将该数据从当前上下文中复制出来并将其传递给您的单独线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-09
    • 2013-09-25
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 2014-01-16
    相关资源
    最近更新 更多