More adventures in Web app threading
Responses in my last post about this were either, "Threading in a Web app isn't a good idea," or a lengthy example that works, but wasn't really what I was after. After looking a little harder, I realized the error of my ways. The goal was to launch a Timer from an HttpModule. This is where I started:
public void Init(HttpApplication application)
{
myTimer = new Timer(new TimerCallback(this.TimerMethod), application.Context, 60000, 60000);
}
static Timer myTimer;
private void TimerMethod(object sender)
{
HttpContext context = ((Application)sender).Context;
MyClass.StaticMethod(context);
}
Then in the class being called by the timer, something like this:
public static void StaticMethod(HttpContext context)
{
Cache cache = context.Cache;
}
The problem there was that the cache object was always null. So at some point someone on the asp.net forums suggested this to me:
public void Init(HttpApplication application)
{
appHandle = GCHandle.Alloc(application.Context, GCHandleType.Normal);
myTimer = new Timer(new TimerCallback(this.TimerMethod), application.Context, 60000, 60000);
}
static Timer myTimer;
protected GCHandle appHandle;
private void TimerMethod(object sender)
{
HttpContext context = (HttpContext)appHandle.Target;
MyClass.StaticMethod(context);
}
This did indeed work. I wasn't sure why, but I did get that it prevented the GC from disposing of the HttpContext object, which otherwise would die. After some toying around, mostly through chance Intellisense encounters, I arrived at this, which works as it should, without the GCHandler:
private void TimerMethod(object sender)
{
HttpContext context = (HttpContext)sender;
MyClass.StaticMethod(context);
}
...with the static method establishing the cache this way:
Cache cache = HttpRuntime.Cache;
What do you know, it works. Watching the output in the debugger, it keeps doing its thing, on and on and on. I'm not sure if the context object in the static method can access the Application object, but seeing as how I have the cache, that's more than adequate.