为了后代......一些测试代码:
class Program
{
    static AutoResetEvent e1 = new AutoResetEvent(false);
    static AutoResetEvent e2 = new AutoResetEvent(false);
    private static object lockObject = new object();
    private static void threadProc()
    {
        lock (lockObject)
        {
            e1.Set();
            e2.WaitOne();
            Console.WriteLine("got event");
        }
    }
    private static int finalized = 0;
    public class finalizerTest
    {
        ~finalizerTest()
        {
            try
            {
                throw new NullReferenceException();
            }
            finally
            {
                Interlocked.Increment(ref finalized);
            }
        }
    }
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem((a) => threadProc());
        e1.WaitOne();
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        {
            finalizerTest f = new finalizerTest();
        }
        //uncommenting this will cause logging to happen as expected
        /*
        while (finalized == 0)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
         */
    }
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Console.WriteLine("in handler -- pre lock");
        e2.Set();
        lock (lockObject)
        {
            Console.WriteLine("in handler");
        }
    }
}
发生的情况是,如果 finalizerTest 因为应用程序离开 main 而最终确定,则输出将显示:
in handler -- pre lock
但是,如果由于 GC.Collect/WaitForPending 终结器而将其终结,则显示为:
in handler -- pre lock
got event
in handler
这意味着在应用程序关闭时从终结器抛出异常的特定情况下,您可能无法获得锁定,但在这种情况下,应用程序和终结队列已经遇到严重问题并且锁定不会让它变得更糟。
在所有其他测试中,我可以认为一切都按预期发生,threadProc唤醒并发生日志记录。