为了后代......一些测试代码:
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
唤醒并发生日志记录。