Solved

Httpcontext.Current.Session problem

Posted on 2009-07-07
7
1,995 Views
Last Modified: 2012-05-07
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?
0
Comment
Question by:xtremereality
  • 4
  • 2
7 Comments
 
LVL 28

Expert Comment

by:strickdd
ID: 24794878
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
 
LVL 12

Expert Comment

by:williamcampbell
ID: 24798241
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
 

Author Comment

by:xtremereality
ID: 24801809
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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 12

Expert Comment

by:williamcampbell
ID: 24808513
Where in the code are you seeing the error?
0
 

Author Comment

by:xtremereality
ID: 24811630
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
 
LVL 12

Accepted Solution

by:
williamcampbell earned 500 total points
ID: 24816102
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
 
LVL 12

Expert Comment

by:williamcampbell
ID: 24816110
...If it is not then you should check again

 I mean in the fucction

threadSafeDoProcess
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Today is the age of broadband.  More and more people are going this route determined to experience the web and it’s multitude of services as quickly and painlessly as possible. Coupled with the move to broadband, people are experiencing the web via …
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question