Загружать объекты в кеш из нового потока - PullRequest
0 голосов
/ 22 апреля 2011

Я пытаюсь использовать класс BackgroundWorker для запуска нового потока, который загружает большое количество объектов в кеш при запуске сайта.

Пока мой код:

private void PreLoadCachedSearches()
{
    var worker = new BackgroundWorker() { WorkerReportsProgress = false, WorkerSupportsCancellation = true };
    worker.DoWork += new DoWorkEventHandler(DoWork);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(WorkerCompleted);
    worker.RunWorkerAsync();
}

private static void DoWork(object sender, DoWorkEventArgs e)
{
    // Do the cache loading...
    var x = HttpContext.Current.Cache; // BUT the Cache is now null!!!!
}

private static void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Logging?
}

Я помещаю код в Global.asax.cs и вызываю PreLoadCachedSearches во время события Application_Start: новый поток запущен, но он завершается неудачно, когда пытается получить доступ к кэшу через HttpContext.Current.Cache, который нуль . Я предполагаю, что HttpContext не существует / не доступен в новой теме, которую я запускаю с помощью BackgroundWorker. Я также попытался переместить код на отдельную страницу и запустить поток вручную, а не через событие Application_Start - та же проблема.
Если я вызываю мой код загрузки кеша в контексте веб-приложения (то есть без потоков), он работает просто отлично.

  • Как мне обойти это? Передать ссылку на кеш основного потока или получить к нему доступ каким-либо образом?

Этот вопрос является продолжением предыдущего вопроса Асинхронная задача в ASP.NET .

Ответы [ 2 ]

3 голосов
/ 22 апреля 2011

У вас нет HttpContext, потому что поток не участвует в обслуживании запроса Http.

Попробуйте HttpRuntime.Cache

1 голос
/ 31 мая 2012

Вы можете сделать это, передав HttpContex.Current в качестве параметра;

private void PreLoadCachedSearches()
{
    var worker = new BackgroundWorker() { WorkerReportsProgress = false, WorkerSupportsCancellation = true };
    worker.DoWork += new DoWorkEventHandler(DoWork);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(WorkerCompleted);
    worker.RunWorkerAsync(HttpContext.Current);
}

private static void DoWork(object sender, DoWorkEventArgs e)
{
    HttpContext.Current = (HttpContext)e.Argument;
    var x = HttpContext.Current.Cache;
}

private static void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Logging?
}
...