I have an ASP.Net application which fires off some background workers using ThreadPool.QueueUserWorkItem(). Most of the time there will be zero background threads running, however it's possible that there could occationally be up to 5-6 executing at a time. Additionally, most will complete within a couple seconds, but it is possible that they could run for as long as 10 minutes.
Given all the different scenarios that could cause a shutdown of an ASP.Net application, I'd like to have these background processes exit gracefully if possible when the application needs to shutdown and they are in the middle of processing.
I don't anticipate having too much of an issue creating a way to signal the processes to stop their work early and clean up within a few seconds of getting the call that the application is being shut down. Although if anyone has specific advice on this I'd certainly appreciate it.
My two main questions are:
1) When would be the appropriate time to tell the background workers to wrap things up. During Application_End? Dispose()? Or perhaps a third option I'm not aware of.
2) If I wait during the above event for the processes to finish before returning, is there a point where not having Application_End return immediately could cause more serious issues for the application than not shutting down the background jobs nicely.
void Application_End(object sender, EventArgs e)
{
//if this for whatever reason takes a non-trivial time to execute, what problems could I encounter?
SignalBackgroundJobsAndWaitForThemToShutDown();
}
Thanks!
The appropriate time is on the Application_End
Now after you signal your background jobs you must wait for them at that point to end, and then let continue, as its seems that you do.
Have in mine, that is good to place a time out on the wait, not wait for ever or else your pool may have problems, or shutdown, then you need to check your pool setting on the max wait to shutdown the pool, there set a value larger than your wait, or just disabled it.
Also have in mine that if you have pool garden, (more than 1 working pools) then the Application_End is called one time for each pool.
I use the same technique on my sites, the same way I signal my threads to stop the same way, I just also log the final end, and check when they are final end, and also I force my routines to stop and not let them run for many time. The Application_End is called on recycle the pool, or when you open the app_offline.htm file, or when you go to close the web service. Personally I have disable the recycles, I do not need them and I only open the app_offline.htm when I make updates. At that moment I wait my pool threads to stop their work.
Related
So, I basically have this:
public void DoThisThing()
{
Task.Run(() =>
{
while(true)
{
//Do things
}
}
}
The start of the application basically calls the DoThisThing() method and enters it's own loop.
So, if I just close the application, what happens to this task? Does it just end? does it continue forever? Does it go on for a little bit until garbage collection gets it? Does it have a way to know the application ended?
I googled, but I couldn't get a simple answer, and I feel like there definitely is one.
The first question is, how this task is even executed. According to the Documentation:
Queues the specified work to run on the ThreadPool and returns a task or Task handle for that work.
Each programm starts with one Thread, but can start further. This one is the Main Thread, the GUI Thread and a few other names. As a general rule, if that main thread is ending, all others threads it started are canceled too. This is a OS level rule, to avoid Zombie Threads with infinite loops running all over the place.
The ThreadPool and all it's data - including sheduled and running Threads - will be collected by the "End of Application" Garbage Colleciton. If not, there is propably some OS features to make sure they end as well. But I prefer not to mention those OS fallbacks, as we really should not be using them ever. There are for cases when even the GC can no longe run properly (like Programm being killed via Task Manager).
One of the big challenges of Multitasking and -threading is keeping the main Thread alive, but without blocking it so further I/O can happen. In a GUI you have that work done for you (with the EventQueue).
All which is said below is implementation details - FOR WINDOWS - and mostly undocumented behavior. Do not rely on any of the information.
As an implementation detail, this task will most likely be scheduled to execute on a thread pool thread.
If the task has not started by the time the process exit starts, it won't matter it was queued in the first place.
If the task is currently executing, then according to some of the implementation details of process shutdown on Windows eventually only one thread will be executing which will not be the one executing this task. So, it will be forcibly terminated in that case.
If the task has already finished execution, whether through completion or by throwing an exception then there's no thread occupied by it. However, if the exception was left unobserved then the finalizer - should it get a chance to execute - will throw that. Please note that finalizers are also not guaranteed to execute under any circumstances.
This page should have been visible, but Microsoft's latest screw up in revoking access to old MSDN blogs continues.
Similarly, if you can manage to track the first link on this page then do so and read it.
P.S.: Here's the link for Raymond's blog. What you'll find from both sources is that only one thread continues the process shutdown.
The answer depends on the content of the while loop.
If the loop is running some logic that runs entirely within the scope and control of the main program, then closing the application will terminate everything.
However, if the loop is calling some external routines or operating system functions (Example: write to a file, open a network connection, run a command, start a batch job, etc), then closing the application will not terminate everything.
Based on your sample, in brief: Yes
Tasks that are created by TPL (using Task.Run or Task.Factory.StartNew) by default are background threads. So closing application will immediately terminate them.
This post could be helpfull.
I'm building a web application in Asp.net. I have long-running tasks that may or may not get finished, as IIS tends to kill long running tasks.
Problem? Nope. I use quartz to periodically restart tasks that die (as changes get saved in the DB, so all we need to do is restart the thread).
But now I'm trying to build my web-application to support scaling out. I'd like to run multiple instances.
So, to handle my long running tasks, I'm thinking of adding a column to my database to note which instance has 'checked out' a given task. However, I'll need to know when the thread dies so that I can make sure it's 'checked in'.
So how do I check when a thread dies?
IIS does not kill threads, it kills AppDomains. The only way I know would be have it write a entry as a heartbeat signal while it is running. If the heartbeat has stopped the thread died.
I'm creating an application that's going to be continuously listening out for incoming signals via TCP until it's either stopped via a button, or the application closes. Being as the PC that the application is running on needs to run quite CPU-heavy stuff, I figured I should run this in a separate thread so that it doesn't hog the CPU.
My thoughts are to use a BackgroundWorker containing an inner-loop in DoWork() that checks the IsCancellationPending flag (this is set via the CancelAsync() method when the user clicks the stop button or exits the application). Is this the best route to go, or is there some other method that's more accepted?
You're doing an IO bound operation, so you shouldn't even be using another thread at all. You should be handling the work asynchronously, in which an event, callback, Task, etc. fires to indicate that you have a message to process, which you can process and then go back to not using any thread at all.
Creating a thread that's just going to spend the vast majority of its time sitting there doing nothing while you wait for network activity isn't a productive use of resources.
I have queue of tasks for the ThreadPool, and each task has a tendency to froze locking up all the resources it is using. And these cant be released unless the service is restarted.
Is there a way in the ThreadPool to know that its thread is already frozen? I have an idea of using a time out, (though i still dont know how to write it), but i think its not safe because the length of time for processing is not uniform.
I don't want to be too presumptuous here, but a good dose of actually finding out what the problem is and fixing it is the best course with deadlocks.
Run a debug version of your service and wait until it deadlocks. It will stay deadlocked as this is a wonderful property of deadlocks.
Attach the Visual Studio debugger to the service.
"Break All".
Bring up your threads windows, and start spelunking...
Unless you have a sound architecture\design\reason to choose victims in the first place, don't do it - period. It's pretty much a recipe for disaster to arbitrarily bash threads over the head when they're in the middle of something.
(This is perhaps a bit lowlevel, but at least it is a simple solution. As I don't know C#'s API, this is a general solution for any language using thread-pools.)
Insert a watchdog task after each real task that updates a time value with the current time. If this value is larger than you max task run time (say 10 seconds), you know that something is stuck.
Instead of setting a time and polling it, you could continuously set and reset some timers 10 secs into the future. When it triggers, a task has hung.
The best way is probably to wrap each task in a "Watchdog" Task class that does this automatically. That way, upon completion, you'd clear the timer, and you could also set a per-task timeout, which might be useful.
You obviously need one time/timer object for each thread in the threadpool, but that's solvable via thread-local variables.
Note that this solution does not require you to modify your tasks' code. It only modifies the code putting tasks into the pool.
One way is to use a watchdog timer (a solution usually done in hardware but applicable to software as well).
Have each thread set a thread-specific value to 1 at least once every five seconds (for example).
Then your watchdog timer wakes every ten seconds (again, this is an example figure only) and checks to ensure that all the values are 1. If they're not 1, then a thread has locked up.
The watchdog timer then sets them all to 0 and goes back to sleep for the next cycle.
Providing your worker threads are written in such a way so that they will be able to set the values in a timely manner under non-frozen conditions, this scheme will work okay.
The first thread that locks up will not set its value to 1, and this will be detected by the watchdog timer on the next cycle.
However, a better solution is to find out why the threads are freezing in the first place and fix that.
I have an application running with the thread,if i perform end-task from the task manager
application is quitting but,in process list an instance will be running(i.e if I do end-task 5 times 5 instances of process running). It might be due to thread.
in this case,if I have to kill all process i need to restart the device :-(.
Manually if I exit It works great.How to overcome from this issue?
I am developing application in c#
As elder_george points out, you have a rogue thread that is preventing the app from exiting and you need to ensure that thread exits when your app shuts down. With CF 3.5 you can usually just set the IsBackground property to truw, though that's not always enough. If the thread is blocking in a system call (like an infinite wait like WaitOne) then the thread will not get schedules and still may not terminate.
The best way to prevent this, and a good practice, is to actually write code that signals your worker threads to shut themselves down. This is often done with a reset event or a boolean flag that the thread checks periodically.
void MyThreadProc()
{
// set this event when the app is shutting down
while(!shutdownEvet.WaitOne(0, false))
{
// do my thread stuff
}
}
This mechanism will also work in CF 2.0 (where IsBackground doesn't exist).
Set IsBackground property on your thread to true.
Hey i got solution for this,
when i perform end task from task manager,control will come next to "Application.Run()" method.
There we can call one user defined function, in that we can perform all the necessary task like killing thread, memory clean up etc.. to end the application smoothly.
Thanks to all for your responses.