Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.12.2012, 00:55   #1
hick91
Новичок
Джуниор
 
Регистрация: 25.12.2012
Сообщений: 5
Печаль operator using and IDisposable

какая раздница между оператором using и методом Dispose?
В плане где нужно использовать первое, где второе? в чем различие?
PS: Ведь using использует реализацию данного интерфейса, дак зачем тогда использовать метод dispose в ручную?
hick91 вне форума Ответить с цитированием
Старый 25.12.2012, 01:19   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

using это концепция RAII, просто синтаксический сахар.(удобный кстати)
не нравится(или не подходит, ибо using это один блок, между процедурами не передашь ресурс) используйте интерфейс напрямую.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 25.12.2012, 01:28   #3
hick91
Новичок
Джуниор
 
Регистрация: 25.12.2012
Сообщений: 5
По умолчанию

Ответ верный, но я немного не правильно задал вопрос.
Эм конкретизируем для маленького блока:
Using ( для объекта p выделяем ресурсы )
{
/.../
}

и

для объекта p выделяем ресурсы
/.../
p.Dispose();

в чем раздница? ( раздница есть, я сам точно не знаю в чем, но препод тонко намекнул на работу Сборщика мусора )
hick91 вне форума Ответить с цитированием
Старый 25.12.2012, 01:38   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в using гарантируется что ресурс будет освобожден, вне зависимости от сборки мусора.
при ручном если вы вдруг забыли освободить ресурс, то его освобождение произойдет только при сборке мусора.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 25.12.2012, 15:16   #5
Reskov
Форумчанин
 
Аватар для Reskov
 
Регистрация: 17.12.2008
Сообщений: 250
По умолчанию

если произойдет экзепшион в блоке using то ресурс все равно будет освобожден, во втором подходе ресурсу будет освобожден только при сборе мусора
using разворачивается в нечто подобное
Код:
try
  {
    byte charset = font1.GdiCharSet;
  }
  finally
  {
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  }
Reskov вне форума Ответить с цитированием
Старый 25.12.2012, 21:00   #6
Selestis
Форумчанин
 
Аватар для Selestis
 
Регистрация: 21.01.2009
Сообщений: 719
По умолчанию

Цитата:
то его освобождение произойдет только при сборке мусора.
Всё гораздо хуже)
Веселье в том, что упомянутый сборщик мусора IDisposable сам по себе нифига не освобождает. Сборщик вызывает только финалайзер ~Class() (если есть), из которого обычно дергают Dispose, да и то не факт что вызовет сразу как собрал. В обычном случае с бесхитростным IDisposable не произойдет вообще ничего, и ресурсы останутся занятыми. Так что в любом случае оставлять IDisposabl'ы на волю сборщика не следует.
Изобретатель велосипедов
Selestis вне форума Ответить с цитированием
Старый 25.12.2012, 22:45   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Сообщение от Selestis Посмотреть сообщение
Всё гораздо хуже)
Веселье в том, что упомянутый сборщик мусора IDisposable сам по себе нифига не освобождает. Сборщик вызывает только финалайзер ~Class() (если есть), из которого обычно дергают Dispose, да и то не факт что вызовет сразу как собрал. В обычном случае с бесхитростным IDisposable не произойдет вообще ничего, и ресурсы останутся занятыми. Так что в любом случае оставлять IDisposabl'ы на волю сборщика не следует.
ну да, кривые классы я не учел.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 26.12.2012, 11:37   #8
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
По умолчанию

Цитата:
Сообщение от hick91 Посмотреть сообщение
Ответ верный, но я немного не правильно задал вопрос.
Эм конкретизируем для маленького блока:
Using ( для объекта p выделяем ресурсы )
{
/.../
}

и

для объекта p выделяем ресурсы
/.../
p.Dispose();

в чем раздница? ( раздница есть, я сам точно не знаю в чем, но препод тонко намекнул на работу Сборщика мусора )
Вот смотри, имеем код (некоторая часть позаимствована с MSDN):
Код:
protected MyMethod(String SmtpServerAddress)
{
// Command line argument must the the SMTP host.
            SmtpClient client = new SmtpClient(SmtpServerAddress);
            // Specify the e-mail sender.
            // Create a mailing address that includes a UTF8 character
            // in the display name.
            MailAddress from = new MailAddress("jane@contoso.com", 
               "Jane " + (char)0xD8+ " Clayton", 
            System.Text.Encoding.UTF8);
            // Set destinations for the e-mail message.
            MailAddress to = new MailAddress("ben@contoso.com");
            // Specify the message content.
            MailMessage message = new MailMessage(from, to);
            message.Body = "This is a test e-mail message sent by an application. ";
            // Include some non-ASCII characters in body and subject.
            string someArrows = new string(new char[] {'\u2190', '\u2191', '\u2192', '\u2193'});
            message.Body += Environment.NewLine + someArrows;
            message.BodyEncoding =  System.Text.Encoding.UTF8;
            message.Subject = "test message 1" + someArrows;
            message.SubjectEncoding = System.Text.Encoding.UTF8;
            // Set the method that is called back when the send operation ends.
            client.SendCompleted += new 
            SendCompletedEventHandler(SendCompletedCallback);
            // The userState can be any object that allows your callback 
            // method to identify this send operation.
            // For this example, the userToken is a string constant.
            string userState = "test message1";
            client.SendAsync(message, userState);
}
Как можно заметить, в этом коде создается экземпляр класса SmtpClient, который отправляет сообщение на электронную почту. Указанный класс имеет реализацию интерфейса IDisposable, но в сумотохе забыли написать в конце:
Код:
client.Dispose();
Теперь представим, что указанный метод вызывается каждые 2 секунды в течении 1 часа. Не факт, что сборщик мусора сможет после каждого исполнения собрать всю память => из-за нашей забывчивости, за этот час уйдет в небытие столько памяти, что стыдно становится. Потом сидишь и с помощью отладчика разбираешься где утечка памяти (есть даже специальные дополнения к VS для этого) и вновь не факт, что ты быстро найдешь причину ошибки. В свою очередь, если бы все классы, которые имеют реализацию интерфейса IDisposable были бы обернуты в блок using, проблемы бы вообще не было. Это я привел упрощенный пример.
Сам стараюсь всегда все что только возможно оборачивать в using - дает о себе знать моя скупость на динамическую память.
Также советую перевести и прочесть небольшую статью на CodeProject, где описывается в какое количество строк рукописного кода может выльиться оператор using. Цитирую и вставляю пару комментариев от себя:
Код:
IDisposable x = ...;//создаем объект, имеющий реализацию интерфейса IDisposable
//оборачиваем весь код, где он используется в try{...}finally{}
try {
 
} 
//при любых условиях выполнить следующий блок
finally 
{ 
x.Dispose(); 
}
Согласись, что кода намного больше
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
operator++ prikolist Общие вопросы C/C++ 17 15.01.2013 16:17
operator= _Bers Общие вопросы C/C++ 2 18.04.2012 06:45
operator== stenl1 Общие вопросы C/C++ 11 27.07.2011 06:38
ошибка: no match for ‘operator<<’ in ‘std::operator<< [with _Traits = std::char_traits<char> Critter Общие вопросы C/C++ 5 08.08.2010 23:38
operator<< Наташенька Общие вопросы C/C++ 6 08.06.2009 18:59