Правильное удаление объекта Singleton IDisposable

Сценарий:

Приложение создает экземпляр одного экземпляра класса, реализующего IDisposable. Экземпляр открывается через статический член, который делает его доступным для всех частей приложения. Один экземпляр необходимо поддерживать в течение всего срока службы приложения.

Вопрос

Насколько критически важно, чтобы метод Dispose вызывался до закрытия приложения и завершения процесса?

Я всегда считал, что в большинстве сценариев, подобных этому, нет необходимости называть Dispose, потому что прекращение процесса естественным образом очищает ресурсы. Я не прав?

Ответ 1

Если при "закрытии вашего приложения" вы подразумеваете, что процесс завершается, вам технически не нужно ничего делать. Ваш процесс завершается, и ОС освобождает эти ресурсы.

Я предполагаю, что это могут быть некоторые неясные угловые случаи, когда какой-то компонент может создать какой-то файл или другой ресурс, и если Dispose не вызывается, это не обязательно будет очищено, даже если ваш процесс завершается.

Я хотел бы привести пример этого, хотя это причудливый угловой случай. Скажем, вы ссылаетесь и используете компонент в своем коде. Когда вы создаете и используете это, он создает файл на 2 ГБ на вашем компьютере. Теперь давайте сделаем еще один шаг и скажем, что этот компонент фактически закрывает сам дескриптор файла, который обращается к этому 2-Гбайт файлу во время его использования из-за ошибки или просто плохого дизайна. Теперь метод Dispose на этом объекте очищает этот файл, но он плохо документирован. По сути, отсутствие вызова Dispose для этого оставит файл на компьютере. Это, безусловно, угловой случай и не приведет к тому, что ваша машина "пропустит" что угодно, но у вас есть файл размером 2 ГБ, который просто сидит там.

Как говорится, наилучшей практикой является вызов Dispose, когда вы детерминированно выполняете свои ресурсы (ресурсы). Вы можете вызвать метод на вашем Singleton - let say Cleanup() - который может запускаться при завершении работы.

Ответ 2

В этом посте есть подробное объяснение того, почему размещение паба событий Другие - хорошая практика.

События объекта .NET и утилита /GC

Так как есть угловые случаи, когда gc не будет собирать Publisher, и он будет продолжать стрелять даже после того, как установлено значение null.

Ответ 3

Если вы хотите убедиться, что ваш метод Dispose вызывается, и если это не смертельная или живая ситуация, вы можете прикрепить к AppDomain.CurrentDomain.ProcessExit.

Если вам абсолютно необходимо убедиться, что ресурсы очищены, используйте исполняемый файл оболочки, который отслеживает ваш основной исполняемый файл и очищает после этого.