Foreground thread not holding up application when I restart the AppDomain - c#

I read on MSDN that the difference between a foreground thread and a background thread is that an application can't terminate until all of its foreground threads have terminated, whereas it won't bother waiting for background threads. I decided to try this out just to get a better understanding of threads.
Thread t = new Thread(Work); //Work() just has the thread sleep for a long time
t.IsBackground = false; //make it a foreground thread
t.Start();
while(true)
{
if(Session["checker"] != null)
{
Session["checker"] = true;
System.Diagnostics.Debug.Write("I'm here!");
}
}
I used a session variable to know if the AppDomain has been restarted since sessions get cleared upon an AppDomain restart.
So when I save the web.config file, it should trigger the AppDomain to restart, which should require it to wait for my long running thread t since t is running in the foreground. However when I touch the web.config file, goes straight into clearing my Session["checker"] and printing out "I'm here!", so I know that my application didn't wait for my thread.
Am I misunderstanding how foreground threads are supposed to work? Shouldn't the AppDomain restart wait for my thread to finish executing before it goes and starts clearing my session variables?
Thanks

Please, pay attention to the word "application" in statement "application can't terminate until all of its foreground threads have terminated". In case of recycling, application is not terminated. During recycling ASP.NET is unloading old AppDomain and loading new one. Everything is done inside single process. Process isn't terminated. In scope of AppDomain unloading, all threads (Background and Foreground) are killed.
So, ASP.NET won't wait for foreground threads to complete during recycling.
Try simple console application which creates a Foreground thread in its Main method. It will work until the thread is terminated.

Related

How to kill application completely regardless thread

My application on startup may start a few thread concurrently. Now based on some condition I would like to completely kill off all the thread regardless the state of other threads.
I have tried App.Current.ShutDown() as well as Application.Current.ShutDown but doesn't work?
You can try
Environment.Exit(0);
You can replace 0 with any code you want from here
You should see Killing all threads that opened by application (and Shutting down a multithreaded application consequently) as I think he provides some solid advice.
A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete.
Set your thread's property IsBackground=true
var t= new Thread();
t.IsBackground = true;
Also See this:
How to: Create and Terminate Threads (C# Programming Guide)
If you need to kill the running application, regardless of state you can either use
Environment.Exit(0); // use -1 if you're exiting with an error, exiting with 0 is considered to have exited without errors.
Or if you really want to use the hammer
Environment.FailFast()
FailFast's documentation says:
Immediately terminates a process after writing a message to the Windows Application event log, and then includes the message in error reporting to Microsoft.
Use the FailFast method instead of the Exit method to terminate your application if the state of your application is damaged beyond repair, and executing your application's try/finally blocks and finalizers will corrupt program resources.
If your other threads are background threads they will end (i.e. abort silently when you shutdown the WPF application which is running on the only foreground thread):
From MSDN:
"...background threads do not prevent a process from terminating. Once all foreground threads belonging to a process have terminated, the common language runtime ends the process. Any remaining background threads are stopped and do not complete."
e.g.
Thread myThread = new Thread();
myThread.IsBackground = true;
ThreadPool threads background ones.

What happens when a Dispatcher created on a background thread is not shutdown? How to make sure that a dispatcher is properly shut down?

The following is one of the remarks on Dispatcher class.
If you create a Dispatcher on a background thread, be sure to shut down the dispatcher before exiting the thread.
What are the consequences if one fails to invoke shut down on a dispatcher created on a background thread?
I have an MFC application which creates a WPF window on a background thread. Consequently, a dispatcher is created. When I close the WPF window first, I get to explicitly invoke shutdown on the dispatcher, but when I close the MFC application, the WPF window closes along.
It seems the dispatcher is being shut down implicitly, or the thread is being aborted. Which is it?
Update:
The following method creates a new thread and opens the wpf window.
public void ShowWindow(SomeObject someObject)
{
System.Threading.Thread thread = new System.Threading.Thread((tuple) =>
{
Tuple<Dispatcher, SomeObject> data = tuple as Tuple<Dispatcher, SomeObject>;
Window window = new WPFWindow(data.Item1, data.Item2);
System.Windows.Threading.Dispatcher.Run();
this.tmp = 0;
});
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.IsBackground = true;
thread.Start(new Tuple<Dispatcher, SomeObject>(Dispatcher.CurrentDispatcher, someObject));
}
So, I put a break along the statement "this.tmp = 0;" and it doesn't get hit when I close the MFC application. Is it safe to assume that the Dispatcher is not being shutdown, but the thread is being aborted?
If the thread is aborted, what are the consequences?
Update:
On another project, I ran into a problem where the GC doesn't seem to be doing its job. It turns out, it's related to a Dispatcher started on a background thread that is not being shutdown. The WPF application's memory usage just kept increasing every time a task is ran on background thread. So, be sure to invoke shutdown on Dispatchers created on a background thread whether you created a Dispatcher object explicitly or not.
Not invoking shutdown on Dispatcher created on background thread will cause memory/resource leak. Dispatcher objects hang onto resources. Hence, the GC aren't able to clean them up.
To make sure that a dispatcher is shut down properly, in my case, I have to spawn the background thread from the MFC side of the application then have the main thread wait on it before it completely shuts down. As Hans Passant pointed out, MFC doesn't wait unless it is explicitly told.
If you don't shutdown dispatcher, thread will stuck in message loop and don't exit
In the main thread you can do something like
Dispatcher.FromThread(thread).InvokeShutDown();
However this will cause the 'Dispatcher.Run()' to generate an exception, so you also need to change it to
try
{
System.Windows.Threading.Dispatcher.Run();
}
catch {}

.net Computer sleep and Disposed is not called

In my application I start a worker thread from a custom user control. When the control is disposed I abort the thread. The problem is that when the computer goes to sleep and the user closes the application my control is not disposed any more.
If I start a thread in my application how can I force it to be stopped when application is closed?
When the control is disposed I abort the thread.
Bad idea. Aborting threads can (and often does) corrupt memory like data structures and such.
If I start a thread in my application how can I force it to be stopped
when application is closed?
You need to set the Thread.IsBackground = true.

In CLR, what is difference between a background and foreground thread?

What is difference between a background and foreground thread ?
See this page:
Foreground threads have the ability to prevent the current application from terminating. The CLR will not shut down an application (which is to say, unload the hosting AppDomain) until all foreground threads have ended.
Background threads (sometimes called daemon threads) are viewed by the CLR as expendable paths of execution that can be ignored at any point in time (even if they are currently laboring over some unit of work). Thus, if all foreground threads have terminated, any and all background threads are automatically killed when the application domain unloads.
From MSDN:
Background threads are identical to
foreground threads with one exception:
a background thread does not keep the
managed execution environment running.
By default, threads are foreground threads, meaning they keep the application alive for as long as
any one of them is running. C# also supports background threads, which don’t keep the
application alive on their own – terminating immediately once all foreground threads have ended.
There are two types of threads -
Foreground Thread
Background Thread
Whenever we open any application, then the main UI thread is of type Foreground thread. This is the default thread type. Suppose when we create any new thread. By default, the thread current type is foreground itself. If you want to change the type of the thread you will have to execute threadName.IsBackground = true;.
Now the main story starts. What is the difference? And why do we need these two types?
Foreground Thread: Suppose we are creating a thread ThreadA. If we need the thread ThreadA to keep executing in spite of all other threads are aborted, even if our main UI thread is no more alive, then in this case we must keep our thread type Foreground. So if you keep your thread foreground type, then even if you close your application, the foreground thread ThreadA will keep running. You can track it also in your task manager.
Background Threads: Now if you change your thread type to be background thread, then this thread is going to be dependent on other foreground threads. Because In the case if none of the thread of type foreground is running anymore, then all the background thread will have to be forcefully aborted.
The important difference between background and foreground threads that is not mentioned yet is the following: a background thread executes only when the number of foreground threads executing is smaller than the number of processors MSDN.
Background thread is going to be killed no matter if it's not finished yet when there will be no active foreground threads.
An example of foreground thread is Application Main thread.
Background thread examples are:
System.Threading.Task class
System.Threading.ThreadPool class
For more information, check out out this MSDN article.
If any of the foreground or background threads terminate, the application dies immediately. It is possible to change the thread from foreground to background and vice versa at any time during application lifetime. CLR creates two kinds of threads to better support AppDomain. CLR will forcibly end any background threads that are running if the foreground thread terminates. Any threads created by native code that enter the managed execution environment are marked as background threads.

Application is not qutting from task manager

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.

Categories