The cross-thread usage of "HttpContext.Current" property and related things - asp.net

I read from < Essential ASP.NET with Examples in C# > the following statement:
Another useful property to know about is the static Current property
of the HttpContext class. This property always points to the current
instance of the HttpContext class for the request being serviced. This
can be convenient if you are writing helper classes that will be used
from pages or other pipeline classes and may need to access the
context for whatever reason. By using the static Current property to
retrieve the context, you can avoid passing a reference to it to
helper classes. For example, the class shown in Listing 4-1 uses the
Current property of the context to access the QueryString and print
something to the current response buffer. Note that for this static
property to be correctly initialized, the caller must be executing on
the original request thread, so if you have spawned additional threads
to perform work during a request, you must take care to provide access
to the context class yourself.
I am wondering about the root cause of the bold part, and one thing leads to another, here is my thoughts:
We know that a process can have multiple threads. Each of these threads have their own stacks, respectively. These threads also have access to a shared memory area, the heap.
The stack then, as I understand it, is kind of where all the context for that thread is stored. For a thread to access something in the heap it must use a pointer, and the pointer is stored on its stack.
So when we make some cross-thread calls, we must make sure that all the necessary context info is passed from the caller thread's stack to the callee thread's stack.
But I am not quite sure if I made any mistake.
Any comments will be deeply appreciated.
Thanks.
ADD
Here the stack is limited to user stack.

There are four things working together to cause the behavior you are asking about:
HttpContext is an instance object whose reference can be found in HttpContext.Current
Thread is also an instance object whose reference can be found in Thread.CurrentThread
Thread.CurrentThread is static but references a different Thread object in every thread
HttpContext.Current actually points to Thread.CurrentThread.ExecutionContext.IllogicalCallContext.HostContext
Conclusions we can draw from the above givens:
Because HttpContext is an instance object and not static we need its reference to access it
Because HttpContext.Current actually points to a property on Thread.CurrentThread, changing Thread.CurrentThread to a different object will likely change HttpContext.Current
Because Thread.CurrentThread' changes when switching threads, HttpContext.Current also changes when switching threads (in this case HttpContext.Current becomes null).
Bringing this all together, what causes HttpContext.Current to not work in a new Thread? The Thread.CurrentThread reference change, which happens when switching threads, changes the HttpContext.Current reference, which prevents us from getting to the HttpContext instance we want.
To reiterate, the only magic thing going on here is Thread.CurrentThread referencing a different object in every Thread. HttpContext works just like any other instance object. Since threads in the same AppDomain can reference the same objects, all we have to do is pass a reference for HttpContext to our new thread. There is no context info to load or anything like that. (there are some fairly serious potential gotchas with passing around HttpContext to other threads but nothing to prevent you from doing it).
A few final side notes I came across while researching:
In some cases a Thread's ExecutionContext is 'flowed' (copied) from one Thread to another. Why then is HttpContext not 'flowed' to our new Thread? Because HttpContext doesn't implement the ILogicalThreadAffinative interface. A class stored in the ExecutionContext is only flowed if it implements ILogicalThreadAffinative.
How does ASP.NET move HttpContext from Thread to Thread (Thread-Agility) if it isn't flowed? I'm not entirely sure, but it looks like it might pass it in HttpApplication.OnThreadEnter().

I think I've found a suitable explanation here: http://odetocode.com/articles/112.aspx
To summarize, the code-behind of HttpContext.Current looks like this:
public static HttpContext get_Current()
{
return (CallContext.GetData("HtCt") as HttpContext);
}
with CallContext functioning as thread-local storage (i.e. each thread will see a different copy of the data and cannot access the copies seen by other threads). Hence, once the current context is initialized on one thread, subsequent accesses by other threads will result in a NullReferenceException, since the property is thread-local to the initial thread.
So yes, your initial explanation was close, in the sense that it is a problem of data being visible only to a single thread.

The backing field of Current is marked as ThreadStatic (I assume), hence it wont be available/initialized in user-created threads.
What it comes down to is, that you should capture the instance of HttpContext.Current in the request thread and then use that instance in your threads, instead of referring to HttpContext.Current.

Related

Passing object via Qt signal/slot across threads

I wish to pass an object using the signal/slot mechanism between threads in Qt. Since I will be passing a pointer to the object, is it safe to call the methods on the object on the receiver's side?
According to this question question the object is not copied (so using original object).
Is this safe? Or am I executing methods on an object belonging to one thread in another thread? Is there a better way to do this?
(I have approximately 20 getters in this class so I don't want to pass individual variables, as well some of the variables are in fact pointers to objects as well)
It is not necessarily safe - signals and slots can be used to cross thread boundaries, so it's possible you could end up trying to access the object from another thread.
The thread in which the slot will be called is determined by the connection type. See the documentation, but as an example:
connect(source, SIGNAL(mySignal(QObject*)), destination, SLOT(mySlot(QObject*)), Qt::DirectConnection);
In this case the function mySlot() will be called from the same thread that the mySignal() signal was emitted in. If your object is not accessed from any threads other than the same thread as the signal emitter this would work fine.
connect(source, SIGNAL(mySignal(QObject*)), destination, SLOT(mySlot(QObject*)), Qt::QueuedConnection);
In this case the function mySlot() will be queued, and called by the event loop of the destination object. So anything done to the object, would happen from within the thread running the event loop of the destination.
I personally find it's best to just stick to passing simple values as arguments. Even though this can work, you would need to add suitable multithreading guards to your QObject if it's likely to be accessed from multiple threads.
First of all, try to use QtConcurrent when you are developing a multi-threaded application. The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded programs without using low-level threading primitives such as mutexes, read-write locks, wait conditions, or semaphores.
After that, safety depends on your class members. If all members are thread-safe, then all will be run safely.

Class requirements for placing object into HttpSession

I am editing a class that is mean to be placed into the session of a servlet use as a key for a hastable of other objects. I do not know what the minimal requirements for an object which can be placed into the HttpSession. what are the minimal requirements for an object which can be placed into the HttpSession?
It should be thread-safe (or at least you should be aware that it can be used by several threads concurrently).
If you plan to save the session to disk or to share it among a cluster of servers, then it should also be Serializable.
And if that object is supposed to be used as a key of a HashMap, then it should override hashCode() and equals() properly, and it would be a good idea to make it immutable.
All objects that are placed in a HttpSession should implement java.io.Serializable.
That's really the only "minimal" requirement.
For scalability you generally want to minimise the overall size of objects that you place in the session as well.

I'm using the Unit of Work Pattern in my DAL, but I need to perform data access in Application_Start. What should I do?

Given:
When using the Unit Of Work pattern with an ORM in ASP.NET, the UnitOfWork object holds a reference to HttpContext.
Question:
But what if I need to perform some data access in Application_Start (especially in IIS7)?
Is the Unit Of Work pattern still viable?
Why is your unit of work holding a reference to HttpContext? To get at session state? If this is the case, have it hold onto something more abstract (i.e. an interface), which in Application_Start will represent a concrete class that does not need HttpContext, and everywhere else will be another (that uses HttpContext internally)

Dispose & Finalize for collections of properties?

I'm looking at some vb.net code I just inherited, and cannot fathom why the original developer would do this.
Basically, each "Domain" class is a collection of properties. And each one implements IDisposable.Dispose, and overrides Finalize(). There is no base class, so each just extents Object.
Dispose sets each private var to Nothing, or calls _private.Dispose when the property is another domain object. There's a private var that tracks the disposed state, and the final thing in Dispose is GC.suppressFinalize(Me)
Finalize just calls Me.Dispose and MyBase.Finalize.
Is there any benefit to this? Any harm? There are no un-managed resources, no db connections, nothing that would seem to need this.
That strikes me as being a VB6 pattern.
I would bet the guy was coming straight from VB6, maybe in the earlier days of .NET when these patterns were not widely understood.
There also is one case were setting an nternal reference to nothing is useful in a call to Dispose: when the member is marked as Withevents.
Without that, you risk having an uncollected object handling events when it really should not be doing that anymore.
It would seem to me that this is something that is NOT needed at all, especially without un-managed resources and data connections.
If you happen to be able to sanitize and post the code we might be able to get a bit more insight, but realistically I can't see a need for it.
Depending on the size of the objects, and how often they are created/destroyed, it could be to ensure GC can happen as early as possible.
It may be, that this pattern was used in other projects and it continues on without understanding why it was used in the first place. Monkey Gardeners
The only reason that I could see for this -- and this is dubious at best -- is if these things are being created and disposed of higher in the "food chain" and there is a potential for some of these domain classes to have either a limited or unmanaged resource at some point.
Even that is sketchy...it sounds like someone came from an unmanaged background and was looking for the .NET equivalent to managing your memory and came across the IDisposable interface.

Would you consider this a singleton/singleton pattern?

Imagine in the Global.asax.cs file I had an instance class as a private field. Let's say like this:
private MyClass _myClass = new MyClass();
And I had a static method on Global called GetMyClass() that gets the current HttpApplication and returns that instance.
public static MyClass GetMyClass()
{
return ((Global)HttpContext.Current.ApplicationInstance)._myClass;
}
So I could get the instance on the current requests httpapplication by calling Global.GetMyClass().
Keep in mind that there is more than one (Global) HttpApplication. There is an HttpApplication for each request and they are pooled/shared, so in the truest sense it is not a real singleton. But it does follow the pattern to a degree.
So as the question asked, would you consider this at the very least the singleton pattern?
Would you say it should not be used? Would you discourage its use? Would you say it's a possibly bad practice like a true singleton.
Could you see any problems that may arise from this type of usage scenario?
Or would you say it's not a true singleton, so it's OK, and not bad practice. Would you recommend this as a semi-quasi singleton where an instance per request is required? If not what other pattern/suggestion would you use/give?
Have you ever used anything such as this?
I have used this on past projects, but I am unsure if it's a practice I should stay away from. I have never had any issues in the past though.
Please give me your thoughts and opinions on this.
I am not asking what a singleton is. And I consider a singleton bad practice when used improperly which is in many many many cases. That is me. However, that is not what I am trying to discuss. I am trying to discuss THIS scenario I gave.
Whether or not this fits the cookie-cutter pattern of a Singleton, it still suffers from the same problems as Singleton:
It is a static, concrete reference and cannot be substituted for separate behavior or stubbed/mocked during a test
You cannot subclass this and preserve this behavior, so it's quite easy to circumvent the singleton nature of this example
I'm not a .NET person so I'll refrain from commenting on this, except for this part:
Would you say its bad practice like a true singleton.
True singletons aren't 'bad practice'. They're HORRIBLY OVERUSED but that's not the same thing. I read something recently (can't remember where, alas) where someone pointed out the -- 'want or need' vs. 'can'.
"We only want one of these", or "we'll only need one": not a singleton.
"We CAN only have one of these": singleton
That is, if the very idea of having two of that object will break something in horrible and subtle ways, yes, use a singleton. This is true a lot more rarely than people think, hence the proliferation of singletons.
A Singleton is an object, of which, there CAN BE only one.
Objects of which there just happens to be one right now are not singleton.
Since you're talking about a web application, you need to be very careful with assuming anything with static classes or this type of pseudo-singleton because as David B said, they are only shared across that thread. Where you will get in trouble is if IIS is configured to use more than one worker process (configured with the ill-named "Web-Garden" mode, but also the # worker processes can be set in machine.config). Assuming the box has more than one processor, whoever is trying to tweak it's performance is bound to turn this on.
A better pattern for this sort of thing is to use the HttpCache object. It is already thread-safe by nature, but what still catches most people is you object also needs to be thread-safe (since you're only going to probably create the instance and then read/write to a lot of its properties over time). Here's some skeleton code to give you an idea of what I'm talking about:
public SomeClassType SomeProperty
{
get
{
if (HttpContext.Current.Cache["SomeKey"] == null)
{
HttpContext.Current.Cache.Add("SomeKey", new SomeClass(), null,
System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromDays(1),
CacheItemPriority.NotRemovable, null);
}
return (SomeClassType) HttpContext.Current.Cache["SomeKey"];
}
}
Now if you think you might need a web farm (multi-server) scale path, then the above won't work as the application cache isn't shared across machines.
Forget singleton for a moment.
You have static methods that return application state. You better watch out.
If two threads access this shared state... boom. If you live on the webserver, your code will eventually be run in a multi-threaded context.
I would say that it is definitely NOT a singleton. Design patterns are most useful as definitions of common coding practices. When you talk about singletons, you are talking about an object where there is only one instance.
As you yourself have noted, there are multiple HttpApplications, so your code does not follow the design of a Singleton and does not have the same side-effects.
For example, one might use a singleton to update currency exchange rates. If this person unknowingly used your example, they would fire up seven instances to do the job that 'only one object' was meant to do.

Resources