Подтвердить что ты не робот

Доступ к HttpContext.Current из разных потоков

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

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

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

Я попытался найти каждый дюйм Stackoverflow, чтобы найти решение, но без везения.

4b9b3361

Ответ 1

В моем приложении есть много кода, который использует 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();

Ответ 2

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

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

Ответ 3

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

В контексте контроллера вы можете отключить пользователя:

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

В потоке установите пользователя "Thread's":

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

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

Ответ 4

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

Ответ 5

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

public class SiteCrawler
{
     HttpContext context = HttpContext.Current;

    public void Method()
    {
        context.WhateverYouWant
    }
}