Access HttpContext.Current from different threads

C#asp.netSessionHttpcontext

C# Problem Overview


I have a C# ASP.NET application which starts about 25 different threads running some methods in a class called SiteCrawler.cs.

In HttpContext.Current.Session I want to save the result of the search made by the user and present it to the user when all the threads are finished running. My problem is that the HttpContext.Current object is null in the spawned threads because it doesn't exist there.

What other options do I have to save user/session specific data without using session because of the limitations when the application is multithreaded?

I have tried to search around every inch of Stackoverflow to find a solution but without any luck....

C# Solutions


Solution 1 - C#

In my application there are a lot of code that uses HttpContext.Current and I can not modify that code.

worker.DoWork() from sample below uses that code. And I had to run it in separate thread.

I came to the following solution:

 HttpContext ctx = HttpContext.Current;
 Thread t = new Thread(new ThreadStart(() =>
                {
                    HttpContext.Current = ctx;
                    worker.DoWork();
                }));
 t.Start();
 // [... do other job ...]
 t.Join();

Solution 2 - C#

Have a look at this article by Fritz Onion: Use Threads and Build Asynchronous Handlers in Your Server-Side Web Code. It's quite long, but your requirement is not too trivial.

Also K. Scott Allen posted a somewhat shorter article about this very issue: Working With HttpContext.Current

Solution 3 - C#

@Rory made a comment above, that certain objects in the HttpContext will become null even if you pass it into the Thread. This happened to me with the User property. So instead you can copy the User to the thread CurrentPrincipal like this:

In the controller context, save off the user:
            _user = HttpContext.Current.User;
            var processThread = new Thread(() => ThreadedCode());
            processThread.Start();
In the thread, set the 'Thread's' user:
    private static void ThreadedCode()
    {
        // Workaround for HttpContext.Current.User being null.
        // Needed for CreatedBy and RevisedBy.
        Thread.CurrentPrincipal = _user;

Note that the HttpContext will only be available for the lifetime of the request. The thread will live on potentially much longer than the request, which is probably why you need a thread in the first place! :)

Solution 4 - C#

Just add the HttpContext.Current to the constructor of your class SiteCrawler.cs

public class SiteCrawler
{
     HttpContext context = HttpContext.Current;
    
    public void Method()
    {
        context.WhateverYouWant
    }
}

Solution 5 - C#

You can save it to the database and then, you can let the user's browser to keep refreshing or using ajax or using the new signalr to check if the result is already written in db. hope it helps.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRaydkView Question on Stackoverflow
Solution 1 - C#Dmitry AndrievskyView Answer on Stackoverflow
Solution 2 - C#Dennis TraubView Answer on Stackoverflow
Solution 3 - C#JessView Answer on Stackoverflow
Solution 4 - C#jjspierxView Answer on Stackoverflow
Solution 5 - C#ysrbView Answer on Stackoverflow