Доступ HttpContext.Current из разных потоков - PullRequest
50 голосов
/ 19 января 2012

У меня есть приложение на C # ASP.NET, которое запускает около 25 различных потоков, выполняющих некоторые методы в классе SiteCrawler.cs.

В HttpContext.Current.Session Я хочу сохранить результат поиска, выполненного пользователем, и представить его пользователю после завершения работы всех потоков.Моя проблема в том, что объект HttpContext.Current является нулевым в порожденных потоках, потому что он там не существует.

Какие еще варианты у меня есть для сохранения данных, относящихся к пользователю / сеансу, без использования сеанса из-за ограничений, когда приложение многопоточное?решение, но без удачи ....

Ответы [ 5 ]

68 голосов
/ 11 октября 2013

В моем приложении много кода, который использует HttpContext.Current, и я не могу изменить этот код.

worker.DoWork() из приведенного ниже примера использует этот код. И мне пришлось запустить его в отдельном потоке.

Я пришел к следующему решению:

 HttpContext ctx = HttpContext.Current;
 Thread t = new Thread(new ThreadStart(() =>
                {
                    HttpContext.Current = ctx;
                    worker.DoWork();
                }));
 t.Start();
 // [... do other job ...]
 t.Join();
11 голосов
/ 19 января 2012

Посмотрите на эту статью Fritz Onion: Используйте потоки и создайте асинхронные обработчики в своем серверном веб-коде . Это довольно долго, но ваше требование не слишком тривиально.

Также К. Скотт Аллен опубликовал несколько более короткую статью об этой самой проблеме: Работа с HttpContext.Current

6 голосов
/ 24 февраля 2016

@ Рори прокомментировал выше, что некоторые объекты в HttpContext станут нулевыми, даже если вы передадите их в поток. Это случилось со мной со свойством User. Таким образом, вместо этого вы можете скопировать пользователя в поток CurrentPrincipal следующим образом:

В контексте контроллера сохраните пользователя:

            _user = HttpContext.Current.User;
            var processThread = new Thread(() => ThreadedCode());
            processThread.Start();

В теме укажите пользователя «Тема»:

    private static void ThreadedCode()
    {
        // Workaround for HttpContext.Current.User being null.
        // Needed for CreatedBy and RevisedBy.
        Thread.CurrentPrincipal = _user;

Обратите внимание, что HttpContext будет доступен только в течение срока действия запроса. Поток будет жить потенциально намного дольше, чем запрос, поэтому, возможно, вам нужен поток в первую очередь! :)

4 голосов
/ 18 февраля 2015

Просто добавьте HttpContext.Current в конструктор вашего класса SiteCrawler.cs

public class SiteCrawler
{
     HttpContext context = HttpContext.Current;

    public void Method()
    {
        context.WhateverYouWant
    }
}
3 голосов
/ 19 января 2012

Вы можете сохранить его в базе данных, а затем разрешить браузеру пользователя продолжать обновлять или использовать ajax, или использовать новый сигнализатор, чтобы проверить, записан ли результат в db. надеюсь, это поможет.

...