J
John
I'm trying to create a context object similar to the HttpContext that could
be used by business objects independent of the origin or the call (ASP.NET
or standalone).
So I started out by using ThreadStatic variables to maintain state for the
current request but soon found out that this doesn't work in ASP.NET since
one request can run on more than one thread. I then discovered an article
(http://authors.aspalliance.com/bbilbro/viewarticle.aspx?paged_article_id=5)
that directed me to the CallContext, which is how the HttpContext class
stores its state.
This brings me to the problem. Although the article's suggestion was
helpful, it is wrong. ThreadStatic and CallContext both suffer the same
problem. If I use ThreadStatic variables or CallContext, whenever ASP.NET
decides to switch threads on me, the state is not available anymore. Here's
a trace of my context object using the CallContext and HttpContext objects
side by side. Notice that when the thread changes (from 2880 to 4048), the
HttpContext class stills has access to its state by not mine.
2880: OnBeginRequest <- HttpModule creates context in this event
MyContext 2880: creating context 0.000061 0.000061
2880: OnAuthenticateRequest 0.001008 0.000155
2880: OnAuthorizeRequest 0.001106 0.000098
2880: OnResolveRequestCache 0.001176 0.000071
4048: OnAcquireRequestState 0.497238 0.496062
4048: OnPreRequestHandlerExecute 0.497352 0.000114
aspx.page Begin Init 0.497505 0.000153
aspx.page End Init 0.497577 0.000072
aspx.page Begin LoadViewState 0.497611 0.000034
aspx.page End LoadViewState 0.497872 0.000261
aspx.page Begin ProcessPostData 0.497923 0.000050
aspx.page End ProcessPostData 0.497982 0.000059
aspx.page Begin ProcessPostData Second Try 0.498024 0.000042
aspx.page End ProcessPostData Second Try 0.498056 0.000032
aspx.page Begin Raise ChangedEvents 0.498088 0.000032
aspx.page End Raise ChangedEvents 0.498143 0.000055
aspx.page Begin Raise PostBackEvent 0.498175 0.000032 <- an attempt is made
to get an instance of the context in a buttonclick event
MyContext 4048: getting context 0.498248 0.000073
MyContext 4048: null in CallContext but not in HttpContext. 0.498291
0.000043
Unhandled Execution Error
Exception of type System.Exception was thrown.
at WebApplication7.MyContext.GetInstance() in
c:\inetpub\wwwroot\webapplication7\mycontext.cs:line 60
at WebApplication7.MyContext.SetData(String pName, Object pValue) in
c:\inetpub\wwwroot\webapplication7\mycontext.cs:line 41
at WebApplication7.WebForm1.Button1_Click(Object sender, EventArgs e) in
c:\inetpub\wwwroot\webapplication7\webform1.aspx.cs:line 56
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain() 0.498490 0.000199
4048: OnError 0.499522 0.001032
4048: OnEndRequest 0.499632 0.000110 <- HttpModule destroys context in this
event
MyContext 4048: destroying context 0.499675 0.000043
4048: OnPreSendRequestHeaders 0.503890 0.004215
4048: OnPreSendRequestContent 0.504082 0.000192
After discovering this behavior I broke out the decompiler and looked at the
source for HttpContext and found the HttpContextWrapper class that seems to
be made aware of thread changes. I figure the HttpContext class moves the
state around at when the thread changes so it remains available.
I know that I could use HttpContext as my state bucket in my context class
(check for HttpContext.Current == null), but I'd rather stay away from that.
Besides this is more fun
. Is there a simple way to reproduce the
HttpContext class' behavior? I don't think I can be made aware of thread
changes without writing my own HttpHandler.
Thanks in advance!
be used by business objects independent of the origin or the call (ASP.NET
or standalone).
So I started out by using ThreadStatic variables to maintain state for the
current request but soon found out that this doesn't work in ASP.NET since
one request can run on more than one thread. I then discovered an article
(http://authors.aspalliance.com/bbilbro/viewarticle.aspx?paged_article_id=5)
that directed me to the CallContext, which is how the HttpContext class
stores its state.
This brings me to the problem. Although the article's suggestion was
helpful, it is wrong. ThreadStatic and CallContext both suffer the same
problem. If I use ThreadStatic variables or CallContext, whenever ASP.NET
decides to switch threads on me, the state is not available anymore. Here's
a trace of my context object using the CallContext and HttpContext objects
side by side. Notice that when the thread changes (from 2880 to 4048), the
HttpContext class stills has access to its state by not mine.
2880: OnBeginRequest <- HttpModule creates context in this event
MyContext 2880: creating context 0.000061 0.000061
2880: OnAuthenticateRequest 0.001008 0.000155
2880: OnAuthorizeRequest 0.001106 0.000098
2880: OnResolveRequestCache 0.001176 0.000071
4048: OnAcquireRequestState 0.497238 0.496062
4048: OnPreRequestHandlerExecute 0.497352 0.000114
aspx.page Begin Init 0.497505 0.000153
aspx.page End Init 0.497577 0.000072
aspx.page Begin LoadViewState 0.497611 0.000034
aspx.page End LoadViewState 0.497872 0.000261
aspx.page Begin ProcessPostData 0.497923 0.000050
aspx.page End ProcessPostData 0.497982 0.000059
aspx.page Begin ProcessPostData Second Try 0.498024 0.000042
aspx.page End ProcessPostData Second Try 0.498056 0.000032
aspx.page Begin Raise ChangedEvents 0.498088 0.000032
aspx.page End Raise ChangedEvents 0.498143 0.000055
aspx.page Begin Raise PostBackEvent 0.498175 0.000032 <- an attempt is made
to get an instance of the context in a buttonclick event
MyContext 4048: getting context 0.498248 0.000073
MyContext 4048: null in CallContext but not in HttpContext. 0.498291
0.000043
Unhandled Execution Error
Exception of type System.Exception was thrown.
at WebApplication7.MyContext.GetInstance() in
c:\inetpub\wwwroot\webapplication7\mycontext.cs:line 60
at WebApplication7.MyContext.SetData(String pName, Object pValue) in
c:\inetpub\wwwroot\webapplication7\mycontext.cs:line 41
at WebApplication7.WebForm1.Button1_Click(Object sender, EventArgs e) in
c:\inetpub\wwwroot\webapplication7\webform1.aspx.cs:line 56
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePo
stBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain() 0.498490 0.000199
4048: OnError 0.499522 0.001032
4048: OnEndRequest 0.499632 0.000110 <- HttpModule destroys context in this
event
MyContext 4048: destroying context 0.499675 0.000043
4048: OnPreSendRequestHeaders 0.503890 0.004215
4048: OnPreSendRequestContent 0.504082 0.000192
After discovering this behavior I broke out the decompiler and looked at the
source for HttpContext and found the HttpContextWrapper class that seems to
be made aware of thread changes. I figure the HttpContext class moves the
state around at when the thread changes so it remains available.
I know that I could use HttpContext as my state bucket in my context class
(check for HttpContext.Current == null), but I'd rather stay away from that.
Besides this is more fun
HttpContext class' behavior? I don't think I can be made aware of thread
changes without writing my own HttpHandler.
Thanks in advance!