Elton Santana
Elton Santana

Reputation: 989

Consume HttpContext Cache with threads

I have the following cache implementation for my application:

public static class Keys
{
    public const string CacheKey = "cachekey";
}

public interface ICache
{
    string QueryCachedData(string param);
}

the data is loaded when the application starts in Global.asax

//Global.asax
protected void Application_Start(object sender, EventArgs e)
{
    //instantiates the repository
    HttpContext.Current.Application[Keys.CacheKey] = repository.getDataView();
}

the implementation recover the data from 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; 
        }
    }
}

at some point i need consume some third party web service with the following class using the cache...

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);
    }
}

...using multi-thread:

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;
}

My problem is that HttpContext.Current.Application is null in the thead context. What options do I have? there are some form to access the HttpContext in thread? or maybe another type of cache that could be shared between the threads?

Upvotes: 0

Views: 507

Answers (1)

Eric J.
Eric J.

Reputation: 150108

My problem is that HttpContext.Current.Application is null in the thead context. What options do I have?

HttpContext.Current is bound to the managed thread processing the current request.

If you need data from the current context for another thread, you need to copy that data out of the current context first and pass it to your separate thread.

Upvotes: 1

Related Questions