public static int Main(string[] args) { Console.WriteLine("Main start"); // Run the finalizer at least once to have its code be jitted BlockingFinalizerOnShutdown finalizableObject; do { finalizableObject = new BlockingFinalizerOnShutdown(); } while (!BlockingFinalizerOnShutdown.finalizerCompletedOnce); // Start a bunch of threads that allocate continuously, to increase the chance that when Main returns, one of the // threads will be blocked for shutdown while holding one of the GC locks for (int i = 0; i < Environment.ProcessorCount; ++i) { var t = new Thread(ThreadMain); t.IsBackground = true; t.Start(); } // Wait a second to give the threads a chance to actually start running Thread.Sleep(1000); Console.WriteLine("Main end"); // Create another finalizable object, and immediately return from Main to have finalization occur during shutdown finalizableObject = new BlockingFinalizerOnShutdown() { isLastObject = true }; return(100); }
public static int Main(string[] args) { Console.WriteLine("Main start"); // Run the finalizer at least once to have its code be jitted BlockingFinalizerOnShutdown finalizableObject; do { finalizableObject = new BlockingFinalizerOnShutdown(); } while (!BlockingFinalizerOnShutdown.finalizerCompletedOnce); // Start a bunch of threads that allocate continuously, to increase the chance that when Main returns, one of the // threads will be blocked for shutdown while holding one of the GC locks for (int i = 0; i < Environment.ProcessorCount; ++i) { var t = new Thread(ThreadMain); t.IsBackground = true; t.Start(); } // Wait a second to give the threads a chance to actually start running Thread.Sleep(1000); Console.WriteLine("Main end"); // Create another finalizable object, and immediately return from Main to have finalization occur during shutdown finalizableObject = new BlockingFinalizerOnShutdown() { isLastObject = true }; return 100; }