views:

123

answers:

3

In this question @Jon skeet referenced this old blog post by the authority Chris Brumme.

I was wondering, do I need to follow all calls to GC.SuppressFinalize(this) with a GC.KeepAlive(this) to avoid weird race conditions where a finalizer can be invoked during the time a disposer is running in heavily multithreaded applications?

If so, can you come up with a sample program that exposes this bug?

+4  A: 

No. GC.KeepAlive doesn't actually do anything; its purpose is to 'fool' the runtime into preventing a specific object from being garbage collected between the start of the method and the call to GC.KeepAlive.

Any method call will keep an object alive in this way: you could pass it to Console.WriteLine, call ToString, or even... GC.SuppressFinalize.

(Or as MSDN puts it:

The KeepAlive method performs no operation and produces no side effects other than extending the lifetime of the object passed in as a parameter.)

Tim Robinson
A: 

Just curious, in what scenario would this give a problem? Say the Dispose() method is past the point where it references any members of the object. What could go wrong with the finalizer freeing the object?

Andomar
nothing if the dispose method is coded correctly, im just curious about the way the CLR fuctions, also adding that extra line in your disposer isnt such a big deal ...
Sam Saffron
+2  A: 

I was asked this recently by a colleague, and posted the answer on my blog, along with example code:

http://nitoprograms.blogspot.com/2009/08/q-if-dispose-calls-suppressfinalize-is.html

You may also be interested in other Disposable blog posts of mine, one of which explores when SuppressFinalize or KeepAlive is required.

Stephen Cleary