GC.Collect
appears to start the garbage collection in a background thread, and then return immediately. How can I run GC.Collect
synchronously -- i
A easier/better way of doing this may be to use mocking and check an expectation that Dispose was called explicitly.
Example using RhinoMocks
public void SomeMethodTest()
{
var disposable = MockRepository.GenerateMock<DisposableClass>();
disposable.Expect( d => d.Dispose() );
// use constructor injection to pass in mock `DisposableClass` object
var classUnderTest = new ClassUnderTest( disposable );
classUnderTest.SomeMethod();
disposable.VerifyAllExpectations();
}
If the method needs to create and then dispose of the object, then I would use and inject a factory class that is able to create the mock object. Example below uses stub on factory as it's not what we are testing for in this test.
public void SomeMethod2Test()
{
var factory = MockRepository.Stub<DisposableFactory>();
var disposable = MockRepository.GenerateMock<DisposableClass>();
factory.Stub( f => f.CreateDisposable() ).Return( disposable );
disposable.Expect( d => d.Dispose() );
// use constructor injection to pass in mock factory
var classUnderTest = new ClassUnderTest( factory );
classUnderTest.SomeMethod();
disposable.VerifyAllExpectations();
}
You can use GC.RegisterForFullGCNotification
, trigger a full collection with GC.Collect(GC.MaxGeneration)
and then the GC.WaitForFullGCComplete
and GC.WaitForPendingFinalizers
methods, but make sure to use this in your tests only, they should not be used for production code.
Finalizers are run on a dedicated, high-priority background thread. From the background in your post, I gather that you can simply do
GC.Collect();
GC.WaitForPendingFinalizers();
The Collect()
will schedule any non-rooted instances for finalization and then the thread will wait for the finalizer thread to complete.
Finalizers always run on a separate thread regardless of whether you're using a concurrent GC or not. If you want to ensure that finalizers have been run, try GC.WaitForPendingFinalizers
instead.