Освобождение ресурсов в C# (Часть 2. IDisposable)

Доброго времени суток! В этой статье я продолжу рассказывать об освобождении неуправляемых ресурсов внутри объектов, в программах, написанных на C#. В предыдущей статье, я рассказывал о том, как можно выполнить эту задачу используя финализаторы, а так же, перечислил негативные стороны применения данного подхода. В этой статье, я расскажу о ещё одной возможности для освобождения ресурсов — о реализации интерфейса IDisposable.

И так, если в объектах создаваемого Вами класса используются неуправляемые ресурсы и Вы хотите разработать механизм для их освобождения, логично реализовать интерфейс IDisposable. Который содержит всего лишь один метод, как не странно, это метод Dispose (без параметров и возвращаемого значения). В данном методе и нужно выполнять работу, нацеленную на освобождение ресурсов. Это может выглядеть примерно так:

//Некий класс
class SomeClass : IDisposable
{
    //Это конструктор
    public SomeClass()
    {
        //Тут выделяются какие-то неуправляемые ресурсы
    }

    //Реализация интерфейса IDisposable
    public void Dispose()
    {
        //Освобождение ресурсов
    }
}

В таком случае, для освобождения ресурсов конкретного объекта нужно вызвать его метод Dispose:

//Создание объекта
SomeClass tmpObject = new SomeClass();

//Работа с объектом...

//Освобождение ресурсов
tmpObject.Dispose();

Но как видно, пользователю класса нужно самому заботиться об освобождении ресурсов. И эта особенность с одной стороны накладывает на программиста дополнительную ответственность, но с другой стороны, четко «видно» место освобождения ресурсов, чего не дает использование финализаторов.

Если Вы пользуетесь объектом класса, который реализует интерфейс IDisposable, т.е. имеет метод Dispose, то не забывайте вызывать этот метод после окончания работы с объектом.

Но зачем нам реализовывать интерфейс IDisposable, только для того, чтобы создать метод для освобождения ресурсов со строго определенным именем?  На самом деле не совсем так! Реализация интерфейса IDisposable позволяет частично автоматизировать вызов метода Dispose. Делается это с помощью ключевого слова using, как показано в примере ниже:

//Создание объекта (в скобках, после ключевого слова using)
using (SomeClass tmpObject = new SomeClass())
{
    //Работа с объектом
} //Тут заканчивается область определения объекта, и автоматически вызывается метод Dispose

Как видите, задача программиста упростилась. Плюс ко всему, метод Dispose будет вызван, даже есть в блоке кода после объявления объекта, произойдет какое-нибудь исключение.

Добавить комментарий