What is the scope of finalizer thread - per application domain or per process?
Looks like it is indeed just one thread per CLR instance within the process - at the moment, anyway. Here's some code to show that:
Test.cs:
using System;class Test{ static void Main() { AppDomain.CreateDomain("First") .ExecuteAssembly("ShowFinalizerThread.exe"); AppDomain.CreateDomain("Second") .ExecuteAssembly("ShowFinalizerThread.exe"); }}
ShowFinalizerThread.cs:
using System;using System.Threading;class ShowFinalizerThread{ static Random rng = new Random(); ~ShowFinalizerThread() { Console.WriteLine("Thread/domain: {0}/{1}", Thread.CurrentThread.ManagedThreadId, AppDomain.CurrentDomain.FriendlyName); if (rng.Next(10) == 0) { Console.WriteLine("Hanging!"); Thread.Sleep(2000); } } static void Main() { new Thread(LoopForever).Start(); } static void LoopForever() { while (true) { new ShowFinalizerThread(); GC.Collect(); GC.WaitForPendingFinalizers(); Thread.Sleep(300); }; }}
Compile each as a console app, then run test.exe (from the command line is easiest, IMO). You'll see that one app domain's finalizer blocks another.
In the future I wouldn't be surprised to see one finalizer thread per core rather than per AppDomain - but it sounds like you'll still have problems :(
You have my deepest sympathy (though not a solution) - once I tracked down a deadlock in an Oracle Blob. We were able to fix that by disposing of it properly, but I know not everything works that nicely - and it was a real pain even finding that one!