Зачем вызывать Dispose() до выхода из main()?
Моя служба.net очищает все свои неуправляемые ресурсы, вызывая resourceName.Dispose() в блоке finally перед выходом из цикла Main().
Я действительно должен сделать это?
Правильно ли я считаю, что не могу утратить какие-либо ресурсы, потому что процесс заканчивается? Windows закроет все дескрипторы, которые больше не используются, верно?
2 ответа
Не существует ограничений на типы ресурсов, которые могут быть инкапсулированы объектом, реализующим IDisposable
, Подавляющее большинство ресурсов, инкапсулированных IDisposable
объекты будут очищены операционной системой, когда процесс завершит работу, но некоторые программы могут использовать ресурсы, о которых операционная система ничего не знает. Например, приложение базы данных, для которого требуется шаблон блокировки, который не поддерживается базовой базой данных, может использовать одну или несколько таблиц, чтобы отслеживать, какие вещи "извлечены" и кем. Класс, который "проверяет" ресурсы с помощью таких таблиц, может обеспечить Dispose
метод, при котором все возвращается обратно, но если программа закрывается без возможности очистки таблицами класса, ресурсы, охраняемые этой таблицей, остаются висящими. Поскольку операционная система не имеет ни малейшего представления о том, что означает любая из этих таблиц, она не может их очистить.
Возможно, в этом конкретном случае можно пропустить это.
Первое, что нужно понять, это то, что при завершении процесса должно быть достаточно для очистки большинства вещей, некоторые неуправляемые ресурсы могут остаться в плохом или незамкнутом состоянии. Например, у вас может быть приложение, которое лицензируется на рабочее место, и когда приложение закрывается, вам необходимо обновить запись базы данных где-нибудь, чтобы освободить вашу лицензию. Если процесс завершается некорректно, это обновление не произойдет, и вы можете в конечном итоге заблокировать людей из вашего программного обеспечения. Просто потому, что ваш процесс завершается, не является оправданием, чтобы не делать очистки.
Однако в мире.Net с шаблоном IDisposable вы можете получить немного больше страховки. Когда процесс завершится, все остальные финализаторы будут запущены. Если шаблон Dispose() реализован правильно (и это "больше", чем должно быть), финализаторы все еще там, чтобы позаботиться о любых оставшихся неуправляемых ресурсах для своих объектов...
Тем не менее, полезно всегда иметь привычку правильно утилизировать эти вещи самостоятельно. И FWIW, просто вызов.Dispose() недостаточно, чтобы сделать это правильно. Ваш вызов.Dispose() должен быть включен как часть блока finally (включая неявный блок finally, который вы получаете с помощью using
заявление).