Я исправлял некоторые проблемы с утечкой памяти в приложении winforms и заметил некоторые одноразовые объекты, которые явно не выбраны (разработчик не вызвал метод Dispose). Внедрение метода Finalize также не помогает, потому что оно не входит в предложение if (disposing)
. Вся статичная регистрация событий и сбор данных были помещены в предложение if (disposing)
. Наилучшей практикой является вызов Dispose, если объект является одноразовым, но, к сожалению, это иногда происходит
Если есть неуправляемые объекты, статические обработчики событий и некоторые управляемые коллекции, которые необходимо очистить при утилизации. Какой способ решить, что нужно делать и что должно выйти из предложения if (disposing)
.
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
disposed = true;
}
}
Он говорит, что управляемые объекты должны находиться в if (disposing)
, который выполняется обычно только при явном вызове метода Dispose разработчиком. Если метод Finalize был реализован, и разработчик забыл вызвать метод Dispose, выполнение, которое приходит сюда через Finalizer, не входит в раздел if (disposing)
.
Ниже приведены мои вопросы.
-
Если у меня есть статические обработчики событий, которые вызывают утечку памяти, где я должен их зарегистрировать? В или из предложения
if (disposing)
? -
Если у меня есть несколько коллекций, которые вызывают утечку памяти, где я должен их очистить? В или из предложения
if (disposing)
? -
Если я использую сторонние одноразовые объекты (например: devExpress winform controls), я не уверен, являются ли они управляемыми или неуправляемыми объектами. Скажем, я хочу избавиться от них при удалении формы. Как я могу узнать, что управляется, а какие - не управляемые объекты? Быть одноразовым не говорит об этом? В таких случаях, как решить, что должно входить и что должно выйти из предложения
if (disposing)
? -
Если я не уверен, что что-то управляло или неуправлялось, что может быть плохими последствиями изъятия/освобождения/отмены регистрации событий из предложения
if (disposing)
? Скажем, он проверяет значение null перед удалением?
Edit
То, что я имею в виду как событие, не регистрирующееся, - это что-то вроде ниже. Издатель - это долговечный экземпляр, а ниже строка - в конструкторе подписчика. В этом случае подписчику необходимо отменить регистрацию события и отправить его перед издателем.
publisher.DoSomeEvent += subscriber.DoSomething;