Check if thread is still running - asp.net

In an ASP.NET MVC application during application_start a new thread gets startet. The thread loads data into the Cache and takes 5 minutes. The application needs to be aware that the loading is in process. Thats why I want to set a flag in an application variable.
I set Application["LoadingCacheActive"] to true when I start the thread.
I dont find a way to set this variable to false when the thread finished. I dont want to use thread.Join, because the application_start has to complete imediately. Inside the created thread I cant set the the variable, because HttpContext.Current is not available.
Any suggestion?

You can use a static AutoResetEvent/ManualResetEvent data member in your Application class. Create the event as not set initially. When you app needs to check whether the thread is finished, it can call WaitOne(0) to test the state of the event. When the thread is finished, it can set the event. If you are using ManualResetEvent, you need to reset it before starting new thread.
You can also use Thread.ThreadState, however, as MSDN states:
Thread state is only of interest in
debugging scenarios. Your code should
never use thread state to synchronize
the activities of threads.

I've had to do similar things. The easiest way is to clear the flag in the last line in the thread.
EDIT: Franci Penov is right, your thread might get killed by a application pool shutdown. However in this case that should not harm you.

Related

Special considerations for using threads in IIS

I'd like to start using asynchronous processing in IIS. Edit: I'm talking about using the task parallel library.
For example, on certain page loads I want to log a bunch of crap, send an email, update some tables, etc. But I don't want to make the user wait for me to log all that crap.
So normally what I do is I have a static Queue that I push the log info onto, and then I have a cron job that calls a special page every 10 minutes whose OnLoad flushes out the queue. This works, but it's kind of clunky to setup, especially when you want to log 50 things. I'd rather do this:
Task.CreateNew(() => Log(theStuff));
However I'm terrified of running tasks in IIS because one slip up and your entire website goes down.
So now I have
SafeTask.FireAndForget(() => Log(theStuff));
This wraps the delegate in some try/catch and passes it into Task.CreateNew. So if someone changes something that affects something else that generates an exception somewhere else that accidentally gets thrown on the task thread, we get a notification instead of a crashed website. Also, the error notification inside the catch is also inside its own try/catch, and the catch for that also has a try/catch that tries to log in a different way.
Now that I can safely run stuff asynchronously in IIS, what other things do I need to worry about before I can start using my SafeTask class?
Every request in IIS and .net is processed in one thread by default. This thread comes from a thread pool called the "Application Pool". Existing threads are reused so you can't really use them for thread state unless you clear or set it every time. You define the size of this thread pool using a formula from MSDN in the machine.config or even your web.config.
Now, every async function call is put on a different thread. This includes async web service calls, async page functions, async delegates, etc. This thread comes from the "application pool" thus reducing the number of thread available for IIS to service new requests.
Most likely, your application will work just fine while using async function calls. In case you are worried or you have a lot of async tasks then you may want to create your own thread pool or look at SmartThreadPool on codeplex.
Hope this helps.
Consider using the page's OnUnload event. Read about it here: http://msdn.microsoft.com/en-us/library/ms178472.aspx
This event fires after the content is sent to the user (so the user isn't blocked while you do work), and should completely satisfy your requirement without introducing additional threads.
Specific to your question, you should be concerned about thread pool exhaustion only if your load and performance testing suggests you're running up against thread limits. If you're not then what you propose is certainly reasonable.

Asynchronous invocation in a ASP.NET application

I'm not talking about asynchronous pages or asynchronous handlers, I just want to know if I should be afraid of any side effect when I invoke an asynchronous method that will end after the page is finished rendering.
Example given: Each time that a user do login, I have to launch a heavy and time consuming SQL operation, but the user doesn't need to know the result of that operation, so I can execute the query using BeginExecuteNonQuery without pass any callback, and finish rendering the page.
My concern is, what happen if the HTTP call ends (because the page is served) and whatever I've executed asynchronously is already running? is ASP.NET or IIS going to cut, destroy, void anything?
Cheers.
That operation will run, even when the request has finished. However, please note that the ASP.NET host aggressively kills threads. When IIS has any reason for unloading or recycling the AppDomain, your background thread will be killed. Unloading happens in several situations. For instance when no new requests have come in for a certain period of time. Or when too many exceptions are fired from the application within a certain period of time. Or when the memory pressure gets too high.
If you need the guarantee, that the operation will finish, I think there are three things you can do:
Speed up the operation so that it can run synchronously, or
Move that that heavy operation to a Windows Service and let that execute it, or
You can hook onto the HostingEnvironment.RegisterObject method (as Phill Haack explains here) (demands full trust) to prevent the AppDomain to go down while that thread is running.
If you have a callback registered, the process will comeback to notify the callback otherwise it will still complete the job. AFAIK - neither ASP.NET or IIS will cut/destroy or void anything as the execution was already ordered and it has to complete.

Getting HttpContext from BackgroundWorker process

I have an ASP.NET site and I've been doing some work refactoring code to try to remove some long running processes (in the order of an hour) from the actual http Request by creating a BackgroundWorker and sending the work off to that to process. This was running fine on cutdown tests but when I applied the logic to the real code I found problems accessing Session variables from the code running in the Background Worker. It seems that the HttpContext object that was passed has a null session and if I ask for HttpContext.Current I get null back.
I'm assuming that this is because they are in a different thread and that the session and HttpContext.Current are both reliant on being in the same thread. Is there any way I can get access to the Session from the background worker or am I stuck with finding all the variables I need from session and putting them in an usable data structure and then putting them back in session (if appropriate) afterwards? It obviously complicates the refactor massively if I need to do this so I'd rather not.
Thanks for any thoughts you might have. I'm open to other suggestions on how I might do this other than BackgroundWorker processes (which were suggested to me in another question).
I'm not sure of all of your requirements, but you may be able to get away with using the Application Cache instead of the Session if you're not looking for the long process to be tied to an individual user's request.
If so, I would try swapping out your use of Session to:
HttpRuntime.Cache.Set("CacheKeyName");
HttpRuntime.Cache.Get("CacheKeyName");
Here's an MSDN link that sheds some light on this.
The text in particular is :
If an asynchronous action method calls a service that exposes methods by using the BeginMethod/EndMethod pattern, the callback method (that is, the method that is passed as the asynchronous callback parameter to the Begin method) might execute on a thread that is not under the control of ASP.NET. In that case, HttpContext.Current will be null, and the application might experience race conditions when it accesses members of the AsyncManager class such as Parameters. To make sure that you have access to the HttpContext.Current instance and to avoid the race condition, you can restore HttpContext.Current by calling Sync() from the callback method.

to create a worker thread and keep it alive throughout my application life time to perform some back ground tasks

I have a req where in i have to create a worker thread and keep it alive throughout my application life time to perform some back ground tasks . so is there any way i can stack tasks to this worker thread when ever needed by my application .?
Update: Even though you've indicated in comments you have to do this in Asp.Net, I'll leave my original content below, as it has some useful links.
Since Asp.Net uses the thread pool to schedule incoming requests, running your background task on the thread pool will take one thread off of it and will impact Asp.Net performance. Thus, you will have to use the Thread class.
To achieve your scenario, you can create a new Thread instance, set its IsBackground property to true and start it. Once started, the thread will wait for an AutoResetEvent (using the WaitOne method) to be set by an incoming request (using the Set met6hod), which will signal the background thread that its task should be processed. Once the task is finished, the background thread will again wait on the event.
This is the simplest implementation, which does not allow passing parameters between the request and the background thread and does not allow more than one tasks to be queued at a time. If you need support for parameters or queueing, you will have to keep a reference to the thread object somewhere it ill be accessible to the incoming requests.
You will also have to consider that your background thread can be killed at any point in time, if IIS decides to recycle the Asp.Net worker process. Also, throwing an exception inside the background thread will cause IIS to recycle the Asp.Net worker process.
There are also some considerations around the identity of the background thread. In particular, a background thread can't easily impersonate the identity of the user on the current incoming request. It is possible, but it will require you to pass the user identity each time a new task is scheduled by a request.
It would be useful if you tell us what language and what platform you are writing your code in.
If it happens to be a Windows platform, there is a thread pool you can "borrow" threads from for your tasks. You can schedule your task on the thread pool by using either the QueueUserWorkItem API (C++) or the ThreadPool.QueueUserWorkItem (C#/.Net). Note there are some implications if your task will be running for a longer time.
You can also create your own thread using either the Thread class (C#/.Net) or the _beginthreadex or the CreateThread API (C++). In this case, you will have to implement a queue for the foreground thread to schedule the tasks on and you will have a loop on the background thread to pick the new tasks and execute them. And of course, you will have to synchronize the access to that queue from both threads using some synchronization primitive like a CRITICAL_SECTION (C++) or the lock statement (C#/.Net).
For Linux or OS X you might look into POSIX threads. I have not done much *nix style programming, so there might be even better alternatives. If you are targeting one of these platforms, add that info to your question and I am sure there will be helpful answers in no time.
Creating a thread is typically done by calling a special primitive (CreateThread() in Win32) and passing it an entry function. That function code in invoked in the newly spawned thread and can do whatever it wishes - for example, it could start a loop and peek tasks from a queue created in advance. Your main thread could post tasks to that queue so that the worker thread processes them. When there're no tasks in the queue the worker thread could simply block on a synchronization primitive (an event for example) waiting for new tasks to be posted.

Polling strategy for an ASP.Net application?

I have an ASP.Net application that needs needs to have some work performed by another machine. To do this I am leaving a message on queue visible to both machines. When the work is done a message is left on second queue.
I need the ASP.Net application to check the second queue periodically to see if any of the tasks are complete.
Where is the best place to but such a loop? Global.asax?
I remember reading somewhere that you can get a function called after an interval. Would that be suitable?
To achieve periodical tasks on asp.net, I've found two acceptable approaches:
Spawn a thread during Application_Start at global.asax, in a while loop (1) Do the work (2) Sleep the thread for an interval.
Again in Application_Start, insert a dummy item into asp.net cache, expires in a certain interval and give that cache item a callback to be called when it's expired. In that callback, you can do the work and insert the cache item back the same way.
In both ways, you need to make sure that your thread keeps working even if there happens an error. You may place a restore code in SessionStart and BeginRequest to check your thread or cache item is there, and renew it if something has happened to it.
I assume that this is done on a regular basis, and that some other process puts the items on the queue?
If that is the case, you might put something in Global.asax that on application start creates a separate thread that simply monitors the queue, you could use a timer to have that thread sleep for X seconds, then check for results.

Resources