Can I detect when a background Thread is killed by the application when the application closes?
Asked Answered
F

2

12

I'm using a thread in C# where I've set the IsBackground property to true. The thread is running some code in a loop until the application closes. When the application is closed the thread also stops executing (because I've set IsBackground = true).

How does the application kill the thread? It seems that it doesn't do it by calling abort because I don't get a ThreadAbortException. Does it happen behind the scenes? I'd like to do some rollback in my finally block of the loop.

I know I could just call abort on the thread myself, but I want to know how the application closes my background thread and if I can react on it from inside the thread. I know I can subscribe to the Application.ApplicationExit event, but I'm running this code in both a service and a winform and I'd prefer catching an exception inside the loop so I'm able to rollback in the finally statement.

Fredenburg answered 13/6, 2012 at 7:27 Comment(3)
You could make it a foreground thread and create a 'global' application shutdown scenario that manually closes the thread.Bambara
Have you looked at the AppDomain.ProcessExit event?Carew
So you're both saying that it happens behind the scenes and I cannot react to it other than creating these kind of custom solutions?Fredenburg
W
5

It seems that it doesn't do it by calling abort because I don't get a ThreadAbortException

It does, the CLR has two ways to abort a thread. The "normal" way, invoked through Thread.Abort(), the thread can see a ThreadAbortException. But there's also a rude abort, works the same way. But minus the TAE and no finally blocks execute. You can't observe it.

Whitten answered 13/6, 2012 at 8:16 Comment(3)
Aha.. Thanks for sorting that out. I couldn't find any documentation on thisFredenburg
Is it mistake on MSDN? msdn.microsoft.com/en-us/library/… When the common language runtime (CLR) stops background threads after all foreground threads in a managed executable have ended, it does not use Thread.Abort. Therefore, you cannot use ThreadAbortException to detect when background threads are being terminated by the CLR.Lara
I don't see any discrepancy between that MSDN article and this answer. Rude aborts can be triggered by application code but you'd need AppDomain.Unload or Environment.Exit, not typically the kind of methods that anybody thinks of first as a way to abort a thread :)Whitten
H
1

The Started thread enters the Running state (i.e., begins executing) when the operating system assigns a processor to the thread. When a Started thread receives a processor for the first time and becomes a Running thread, the thread executes its ThreadStart delegate, which specifies the actions the thread will perform during its lifecyle. When a program creates a new Thread, the program specifies the Thread's ThreadStart delegate as the argument to the Thread constructor.

A Running thread enters the Stopped (or Dead) state when its ThreadStart delegate terminates. In your case your main thread is terminates. So, your ThreadStart delegate object does not remains in memory. When there are no references to the thread object, the garbage collector can remove the thread object from memory.

Hemicellulose answered 13/6, 2012 at 8:1 Comment(4)
Thanks for a good explanation of this. I ended up using the AppDomain.ProcessExit event as Botz3000 suggested. I can then call thread.Abort() when this event is raised. It seems to work well.Fredenburg
This answer is incorrect. An abandoned background thread is not aborted by the GC collecting it. It is forcefully aborted by the runtime regardless of what strong references you have to the managed thread object. See Hans' answer for the explanation.Uralian
@JoshEinstein: May be you are correct, but Hans did not explain how CLR abort the thread abnormally.... Can u explain?Hemicellulose
It kills it (presumably using a Windows function such as ExitThread) outside of your control without running your managed code. If you need to ensure code runs upon thread termination, you should signal your background threads to terminate before exiting from your main thread.Uralian

© 2022 - 2024 — McMap. All rights reserved.