Reputation: 4155
Recently, I discovered a bug in our system where a property in a dll was shared. In the case of ASP.Net, this caused issues with thread safety.
protected static object Data { get; set; }
In order to fix this with the smallest change possible, I swapped out the inner property to make use of HttpContext.Current.Items
to store and retrieve the value. This works in the case of our website(s).
protected static object Data
{
get
{
return HttpContext.Current.Items[DataKey] as object;
}
set
{
HttpContext.Current.Items[DataKey] = value;
}
}
However, we also have an exe that references this dll. When this runs it (obviously) does not have a reference to HttpContext.Current
.
Is there an alternative object I can use that will work for both asp.net and/or the exe. I'm willing to use branching logic to work out which property to hit if necessary, so long as I only need to change this property (obviously one solution for both is preferred.
Upvotes: 0
Views: 1943
Reputation: 4155
So the [ThreadStatic]
attribute can potentially help in this scenario, but it comes with caveats.
Scott Hanselman wrote a Blog Post regarding the use of ThreadStatic
. In particular, this part is relevant:
Don't slap a [ThreadStatic] attribute on a static member when you're operating within ASP.NET as chances are you don't control the thread life...you inherit a worker thread. ThreadStatic gives you thread local storage, not HttpContext local storage!
Basically, because the (IIS) Worker has a tendency to re-use threads from the App Pool, its generally unadvisable to use this attribute for web processes.
In order to apply this, whilst still maintaining thread safety for Web requests (and only touching the property), you can use branching logic to determine which of the sections to store/retrieve your data from:
[ThreadStatic]
private static object _data;
protected static object Data
{
get
{
if (HttpContext.Current != null)
return HttpContext.Current.Items[DataKey] as object;
else
return _data;
}
set
{
if (HttpContext.Current != null)
HttpContext.Current.Items[DataKey] = value;
else
_data = value;
}
}
Upvotes: 3