Я исправлял некоторые проблемы с утечкой памяти в приложении winforms и заметил некоторые одноразовые объекты, которые не были удалены явно (разработчик не вызвал метод Dispose). Реализация метода Finalize также не помогает, потому что он не входит в предложение if (dising)
. Вся отмена регистрации статических событий и очистка сбора помещены в предложение if (удаление)
. Лучше всего вызывать Dispose, если объект является одноразовым, но, к сожалению, это иногда случается
Если есть неуправляемые объекты, статические обработчики событий и некоторые управляемые коллекции, которые необходимо очистить при удалении. Как решить, что должно входить и что должно быть исключено из предложения if (dising)
.
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's 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 (Dispose)
, который выполняется нормально только тогда, когда разработчик явно вызывает метод Dispose. Если был реализован метод Finalize и разработчик забывает вызвать метод Dispose, выполнение, которое происходит здесь через Finalizer, не попадает в раздел if (dispose)
.
Ниже приведены мои вопросы.
Если у меня есть статические обработчики событий, вызывающие утечки памяти, где мне отменить их регистрацию? В или из пункта if (удаление)
?
Если у меня есть коллекции, вызывающие утечки памяти, где мне их очистить? В или из пункта if (удаление)
?
Если я использую одноразовые объекты сторонних производителей (например, элементы управления winform devExpress), я не уверен, являются ли они управляемыми или неуправляемыми объектами. Допустим, я хочу избавиться от них при удалении формы. Как я могу узнать, какие объекты являются управляемыми, а какие - неуправляемыми? Одноразовость этого не говорит? В таких случаях, как решить, что должно входить и что должно быть исключено из if (dising)
пункта?
Если я не уверен, что что-то управляемое или неуправляемое, каковы могут быть плохие последствия удаления / очистки / отмены регистрации событий из пункта if (удаление)
? Допустим, перед удалением он проверяет наличие null?
Edit
То, что я имею в виду под отменой регистрации события, выглядит примерно так, как показано ниже. Издатель - это долгоживущий экземпляр, и строка ниже находится в конструкторе подписчика. В этом случае подписчик должен отменить регистрацию события и утилизировать его перед издателем.
publisher.DoSomeEvent += subscriber.DoSomething;