There is nothing about what finalizers do that need the separate thread, however consider this:
- When GC runs on generation 0 and 1, the "ephemeral" generations, managed threads are suspended
- Concurrent or background collection can run on generation 2 after the managed threads have resumed (there's a lot of information about this in MSDN: Fundamentals of Garbage Collection)
However, a plausible naive solution would be to do the following:
- Suspend all the threads (or possibly leave the thread that triggered GC running, just have it do GC instead)
- Do the garbage collection, with everything this entails
- Resume all threads
This would probably be quite simple to implement. The GC operation has free access to all the data structures related to the heaps and is free to do anything it wants, because no other thread that accesses these things are running.
However, this would make the program have "quite long" pauses from time to time, and would be quite unacceptable in most applications.
So instead the team that works on the GC has opted for the solution of suspending for the smallest possible time, suspending only when needed (generation 0 and 1 collection) while leaving the application running while generation 2 is collected. This is more difficult. Note, this is assumptions on my part, I don't have access to the actual design documentation or any solid information about this. The assumptions are based on the official documentation.
So back to the finalizer thread. These objects are already "dead" and slated for collection, so in lieu of the above design decision, why bother one of the main threads doing application work with this? Since the GC is already doing things in the background, handling finalization of dead objects in the same way seems like a good decision.