Нужно ли вызывать GC.KeepAlive (this) в моем методе Dispose? - PullRequest
4 голосов
/ 03 мая 2009

В этот вопрос @Jonkeet ссылался на это старое сообщение в блоге авторитетным Крисом Браммом.

Мне было интересно, нужно ли выполнять все вызовы на GC.SuppressFinalize(this) с GC.KeepAlive(this), чтобы избежать странных условий гонки, когда финализатор может быть вызван во время работы диспетчера в сильно многопоточных приложениях?

Если это так, вы можете придумать пример программы, которая выявляет эту ошибку?

Ответы [ 3 ]

7 голосов
/ 03 мая 2009

Нет. GC.KeepAlive на самом деле ничего не делает; его цель состоит в том, чтобы «обмануть» среду выполнения, чтобы предотвратить сбор мусора между объектом с момента запуска метода и до вызова GC.KeepAlive.

Любой вызов метода будет поддерживать объект таким образом: вы можете передать его Console.WriteLine, вызвать ToString или даже ... GC.SuppressFinalize.

(Или, как MSDN выражается:

Метод KeepAlive не выполняет никаких операций и не создает никаких побочных эффектов, кроме продления времени жизни объекта, передаваемого в качестве параметра.)

2 голосов
/ 11 ноября 2009

Недавно меня спросил коллега, и он опубликовал ответ в своем блоге вместе с примером кода:

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

Вы также можете быть заинтересованы в других моих одноразовых постах в блоге, одна из которых исследуется, когда требуется SuppressFinalize или KeepAlive.

0 голосов
/ 03 мая 2009

Просто любопытно, в каком сценарии это создаст проблему? Скажем, метод Dispose () прошел точку, в которой он ссылается на любые члены объекта. Что может пойти не так с финализатором, освобождающим объект?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...