Httpcontext.Current.Session problem

Hi all,
I'm having a problem with session variable in a thread.

Inside a thread I'm using this code

context.Session["something"] = "some text";

I'm passing to the new thread the context object: HttpContext.Current

When I debug the code I can see the httpContext is passed correctly to the new thread, but when I try to set the session I have an exception saying the session is null.

After I run the thread I'm redirecting to a new page.
Inside this new page I wanna read the value of the session and this is empty.

Any suggestion?
xtremerealityAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

strickddCommented:
I think what is going on is that HttpContext.Current is not thread safe. You may want to just store the value of the session to a DB and then read it out when you need it.
0
williamcampbellCommented:
The threads are not going to share context, that is a thread-specific aspect. For something of an analogy - when a web server receives multiple requests it uses multiple threads to answer them. Each thread handles an individual request and does not know about the others. In a similar way, the child thread does not know about the parent thread's httpcontext.

 You need to pass the Parent HttpContext to the child Thread (ThreadStart  Maybe) or pass The instance of HttpApplicationState
0
xtremerealityAuthor Commented:
Thanks for the answer william

This is what I'm doing in practice:
I did a interface called IProcessProvider

public interface IProcessProvider
{
    ProcessResult GetProcess(
                                string path,
                                Int32 Id,
                                System.Web.HttpContext context
                            );
}

and another one

public interface IThreadManager
{
    bool IsCompleted { get; }
    List<ProcessResult> Results { get; }
}

this class is to manage the process result

public class ProcessResult
{
    private string resultMessage;

    public string ResultMessage
    {
        get { return resultMessage; }
    }

    public ProcessResult(string resultMessage)
    {
        this.resultMessage = resultMessage;
    }
}


here the class that implement the IthreadManager

public class ThreadManager : IThreadManager
{
    private const string NO_ERRORS = "-1";

    private string path;
    private Int32 Id;
    private HttpContext context;

    private List<ProcessResult> results = new List<ProcessResult>();

    public string PATH
    {
        get { return path; }
    }

    public System.Web.HttpContext CONTEXT
    {
        get { return context; }
    }

    public List<ProcessResult> Results
    {
        get { return results; }
    }

    private IProcessProvider[] getAvailableProviders()
    {
        return new IProcessProvider[] {
        new Provider1()};
    }

    public ThreadManager(string path, int Id, HttpContext context)
    {
        this.path = path;
        this.Id = Id;
        this.context = context;
    }

    private bool isCompleted = false;
    public bool IsCompleted
    {
        get { return isCompleted; }
    }


    public void GetProcess()
    {
        isCompleted = false;
        try
        {
            List<Thread> threads = new List<Thread>();
            foreach (IProcessProvider provider in getAvailableProviders())
            {
                Thread thread = new Thread(new ParameterizedThreadStart(threadSafeDoProcess));
                threads.Add(thread);
                thread.Start(provider);
            }

            foreach (Thread thread in threads)
            {
                thread.Join();
            }
        }
        finally
        {
            isCompleted = true;
        }
    }

    private object sync = new object();
    private void threadSafeDoProcess(object parameter)
    {
        IProcessProvider provider = parameter as IProcessProvider;
        if (provider != null)
        {
            ProcessResult processResult = provider.GetProcess(path, Id, context);

            // lock on sync object
            lock (sync)
            {
                // Add data to the collection. Only one thread at the time
                // can do that
                results.Add(processResult);
               
            }
            // here the lock is released
        }
    }
}


And finally the provider that does the job I need

public class Provider1 : IProcessProvider
{
    private string message = string.Empty;
    private const string NO_ERRORS = "-1";

    public ProcessResult GetProcess(
                                        string path,
                                        Int32 Id,
                                        System.Web.HttpContext context
                                    )
    {
      // Implementation
    }
}


In order to use the code above this is what I'm doing from asp.net page



                ThreadManager threadMgr = new ThreadManager(path, Id, HttpContext.Current);

                Session["ThreadMgr"] = threadMgr;
               
                // run the threadMgr in a secondary worker thread
                Thread thread = new Thread(new ThreadStart(threadMgr.GetProcess));
                thread.Start(); // this method is released immediately

I'm supposing I'm passing the correct httpContext to the process or maybe I'm doing something wrong?
I don't understand what's wrong with this logic

Thanks again
0
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

williamcampbellCommented:
Where in the code are you seeing the error?
0
xtremerealityAuthor Commented:
See the comment with "<----" below

public class Provider1 : IProcessProvider
{
    private string message = string.Empty;
    private const string NO_ERRORS = "-1";

    public ProcessResult GetProcess(
                                        string path,
                                        Int32 Id,
                                        System.Web.HttpContext context   <---- sometime context.Session is null sometime not
                                    )
    {
      // if I write here
     context.Session["something"] = "foo"; <--- here I get that the instance is null

    }
}
0
williamcampbellCommented:
In this code here

    public ThreadManager(string path, int Id, HttpContext context)
    {
        this.path = path;
        this.Id = Id;
       if ( context == NULL )
       {
             throw Exception ( "Doh!" );
       }
      else
             this.context = context;
   }

    Is Context ever Null? If it is not then you should check again

    if ( context == NULL )
   {
          // context has been freed by system
   }
   else
          ProcessResult processResult = provider.GetProcess(path, Id, context);

   Let me know the results of this check
 


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
williamcampbellCommented:
...If it is not then you should check again

 I mean in the fucction

threadSafeDoProcess
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.