Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to call GC.KeepAlive(this) in my Dispose method?

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?

like image 465
Sam Saffron Avatar asked May 03 '09 11:05

Sam Saffron


People also ask

Does GC Call Dispose?

The GC does not call Dispose , it calls your finalizer (which you should make call Dispose(false) ).

Does Dispose get called automatically?

Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.

When should you call Dispose?

There is a simple guideline: if you have finished with an object whose type implements IDisposable then call Dispose() on it; you should use a using block to do this.

How do I keep my GC alive?

Enter GC. KeepAlive() . The purpose of GC. KeepAlive() is to force the garbage collector to treat the object as still live, thereby preventing it from being collected, and thereby preventing the finalizer from running prematurely.


2 Answers

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.)

like image 115
Tim Robinson Avatar answered Sep 28 '22 07:09

Tim Robinson


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

https://blog.stephencleary.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.

like image 38
Stephen Cleary Avatar answered Sep 28 '22 07:09

Stephen Cleary