<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=3162779</guid>
        <pubDate>Fri, 29 Jun 2012 20:13:24 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=3162779</link>
        <description><![CDATA[juice: Он там вызывается, проскроль последний блок исходного кода для класса потомка.]]></description>
        <author>juice</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=3122811</guid>
        <pubDate>Sat, 21 Apr 2012 11:28:23 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=3122811</link>
        <description><![CDATA[_Hamlet: Привет.<br>Конечно, топик довольно старый, но все же такой вопрос: А в переопределенном методе void Dispose(bool) в конце не нужно вызвать Dispose базового класса?]]></description>
        <author>_Hamlet</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828539</guid>
        <pubDate>Tue, 08 Jan 2008 16:12:05 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828539</link>
        <description><![CDATA[Miha_Dnepr: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1828523'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>juice &#064; <time class="tag-quote__quoted-time" datetime="2008-01-08T16:02:35+00:00">08.01.08, 16:02</time></span><div class='quote '>необработанное исключение, возникшее в потоке финализатора, по умолчанию разрушает весь процесс.</div></div><br>
Вот это я и хотел узнать...<br>
Теперь вроде все ясно, спасибо.]]></description>
        <author>Miha_Dnepr</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828523</guid>
        <pubDate>Tue, 08 Jan 2008 16:02:35 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828523</link>
        <description><![CDATA[juice: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1828474'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Miha_Dnepr &#064; <time class="tag-quote__quoted-time" datetime="2008-01-08T15:14:32+00:00">08.01.08, 15:14</time></span><div class='quote '>Решение, впринципе, работает... Думаю, в случаях, когда потенциально может возникнуть ошибка при освобождении ресурсов, таки заключать в блок try/catch &quot;опасный&quot; код.<br>
Кстати, а при таком подходе блокируется ли дальнейший процесс сборки? Ну, по-крайней мере, пока юзерь не нажал &quot;Ок&quot;  </div></div><br>
<br>
Нужно стараться, что бы удаление объекта происходило без возникновения исключений. Насамом деле нет &quot;правильного&quot; способа восстановления после исключения во время выполнения очистки в Dispose. Если при очистке объекта возникает исключение, то единственный выход, попытаться попробовать очистить объект заново или согласиться с тем, что часть ресурсов не может быть освобождена. Поэтому в коде очистки нужно проверить все ссылки на объекты, к которым мы будем обращаться внутри Dispose, и что эти ссылки не являются неопределенными, и что методы которые мы вызываем не приводят к возникновению исключений. Это аксиома. При этом исключение в Dispose еще не самый худший вариант, хуже если оно вызвано финализатором, необработанное исключение, возникшее в потоке финализатора, по умолчанию разрушает весь процесс.]]></description>
        <author>juice</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828474</guid>
        <pubDate>Tue, 08 Jan 2008 15:14:32 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828474</link>
        <description><![CDATA[Miha_Dnepr: Мне просто стало интересно, какова физика процесса... Ну, вот, допустим, дошла очередь до сборки мусора. Объекты, не имеющие &quot;деструкторов&quot; (уж, извините, мне это слово привычнее..) уже удалились, и тут, о - чудо&#33; Запускается отдельный поток по сборке &quot;ресурсоемкого&quot; мусора, и в этом потоке вылазит исключение. Что произойдет с дальнейшим процессом сборки, как &quot;поступит&quot; CLR в этом случае? продолжится ли освобождение остальных объектов, с занятыми ресурсами?<br>
<br>
По-поводу try/catch...<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;protected virtual void Dispose(bool isDisposing){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(true == _disposed){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;try {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new Exception(&quot;Ex!&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;catch{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox.Show(&quot;Опаньки!&quot;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Ну, или плюс ко всему в лог какой-нибудь записать...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_disposed = true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Решение, впринципе, работает... Думаю, в случаях, когда потенциально может возникнуть ошибка при освобождении ресурсов, таки заключать в блок try/catch &quot;опасный&quot; код.<br>
Кстати, а при таком подходе блокируется ли дальнейший процесс сборки? Ну, по-крайней мере, пока юзерь не нажал &quot;Ок&quot; ;)]]></description>
        <author>Miha_Dnepr</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828456</guid>
        <pubDate>Tue, 08 Jan 2008 15:00:00 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828456</link>
        <description><![CDATA[juice: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1828420'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Miha_Dnepr &#064; <time class="tag-quote__quoted-time" datetime="2008-01-08T14:27:54+00:00">08.01.08, 14:27</time></span><div class='quote '>А еще прикольнее, когда не вызываешь явно GC.Collect и не обнуляешь &quot;c = null;&quot;, а просто закрыть приложение.</div></div><br>
Собственно разница небольшая, т.к. после закрытия приложения, освобождается домен, а следовательно и отрабатывает сборщик мусора. Объект имеет finalizer и явно не освобождался, он ставится на завершение в очередь.<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1828420'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Miha_Dnepr &#064; <time class="tag-quote__quoted-time" datetime="2008-01-08T14:27:54+00:00">08.01.08, 14:27</time></span><div class='quote '>Как с этим правильно бороться? </div></div><br>
<br>
Первое, что приходит в голову это подавить возможные исключения путем заключения кода который бросает исключение в блок try/catch, хотя если код в Dispose может сгенерировать исключение, это сведетельствует о том, что там есть, что то, кроме освобождения ресурсов, что является грубой ошибкой.]]></description>
        <author>juice</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828420</guid>
        <pubDate>Tue, 08 Jan 2008 14:27:54 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828420</link>
        <description><![CDATA[Miha_Dnepr: Да, кстати, по поводу возникновения ошибки / исключения в методе Dispose(bool).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;public class MyClass : IDisposable{</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;private bool _disposed = false;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;#region IDisposable Members</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;public void Dispose(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dispose(true);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GC.SuppressFinalize(this);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;#endregion</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;protected virtual void Dispose(bool isDisposing){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(true == _disposed){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throw new Exception(&quot;Ex!&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_disposed = true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;~MyClass(){</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dispose(false);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
Затем, в вызывающем коде<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp;public partial class Form1 : Form</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;MyClass c = new MyClass();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;public Form1()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;InitializeComponent();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;private void Form1_Load(object sender, EventArgs e)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;private void button1_Click(object sender, EventArgs e)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c = null;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GC.Collect();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
<br>
Угадайте, что происходит? ;) А еще прикольнее, когда не вызываешь явно GC.Collect и не обнуляешь &quot;c = null;&quot;, а просто закрыть приложение.<br>
Как с этим правильно бороться?]]></description>
        <author>Miha_Dnepr</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828417</guid>
        <pubDate>Tue, 08 Jan 2008 14:26:24 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828417</link>
        <description><![CDATA[juice: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1828412'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Miha_Dnepr &#064; <time class="tag-quote__quoted-time" datetime="2008-01-08T14:15:49+00:00">08.01.08, 14:15</time></span><div class='quote '>По-идее, вместо true должен быть this...</div></div><br>
Абсолютно коректное замечание.<br>
Вот даж на эту тему есть статейка http://msdn2.microsoft.com/en-us/library/ms182269.aspx<br>
+1.<br>
<br>
Код поправил.]]></description>
        <author>juice</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828412</guid>
        <pubDate>Tue, 08 Jan 2008 14:15:49 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828412</link>
        <description><![CDATA[Miha_Dnepr: <strong class='tag-b'>juice</strong>, Хорошая статья :) спасибо.<br>
Я вот нашел одно &quot;Но&quot;. Вот цитатка из МСДН:<br>
<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '><br>
public static void SuppressFinalize (Object obj)<br>
<br>
Parameters<br>
obj<br>
The object for which a finalizer must not be called. <br>
</div></div><br>
вот из твоего примера:<div class='tag-quote'><span class='tag-quote-prefix'>Цитата</span> <div class='quote '>GC.SuppressFinalize(true);</div></div><br>
По-идее, вместо true должен быть this...<br>
Хотя, компилится и выполняется и с &quot;true&quot; :)]]></description>
        <author>Miha_Dnepr</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828013</guid>
        <pubDate>Tue, 08 Jan 2008 08:20:35 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828013</link>
        <description><![CDATA[PIL: аут :) Новый Год виноват, извиняюсь ))]]></description>
        <author>PIL</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828010</guid>
        <pubDate>Tue, 08 Jan 2008 08:19:48 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828010</link>
        <description><![CDATA[juice: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1828006'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>PIL &#064; <time class="tag-quote__quoted-time" datetime="2008-01-08T08:16:58+00:00">08.01.08, 08:16</time></span><div class='quote '>juice, зачед, замечательная статья, надо в FAQ <br>
Еще добавил бы, что майкрософты проверяют _isDisposed при обращении к обьекту, и если вызывался Dispose() для него - бросаются исключениями. </div></div><br>
Спасибо. Из текста выше.<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=217985&view=findpost&p=1827516'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>juice &#064; <time class="tag-quote__quoted-time" datetime="2008-01-07T14:48:36+00:00">07.01.08, 14:48</time></span><div class='quote '>Все общедоступные методы вашего типа не должны выполняться после вызова метода клиентом метода Dispose(), это легко реализовать путем проверки переменной _desposed в теле метода. В случае если объект уже был освобожден, необходимо сгенерировать исключение ObjectDisposed. </div></div><br>
;)]]></description>
        <author>juice</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828006</guid>
        <pubDate>Tue, 08 Jan 2008 08:16:58 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1828006</link>
        <description><![CDATA[PIL: <strong class='tag-b'>juice</strong>, зачед, замечательная статья, надо в FAQ :)<br>
Еще добавил бы, что майкрософты проверяют _isDisposed при обращении к обьекту, и если вызывался Dispose() для него - бросаются исключениями.]]></description>
        <author>PIL</author>
        <category>.NET FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1827516</guid>
        <pubDate>Mon, 07 Jan 2008 14:48:36 +0000</pubDate>
        <title>Стандартная модель освобождения ресурсов .NET</title>
        <link>https://forum.sources.ru/index.php?showtopic=217985&amp;view=findpost&amp;p=1827516</link>
        <description><![CDATA[juice: Представляется статья, в которой я попытаюсь осветить один из аспектов управления  ресурсами на платформе .NET, а именно стандартной модели освобождения ресурсов посредством  реализации интерфейса IDisposable в связке с завершителем (finalizer).<br>
<br>
Предлагаю, Вам маленький тест для самопроверки знаний:<br>
•	Знаю ли я, что такое стандартная модель освобождения ресурсов?<br>
•	Уверен  ли я, что корректно реализую стандартную модель освобождения ресурсов в собственных типах?<br>
•	Могу ли я объяснить, что такое завершитель объекта?<br>
•	Знаю ли я, что такое неуправляемые ресурсы, а также какие требования к программному коду порождает их использование в наших программах?<br>
•	Знаю ли я, где предпочтительней использовать завершитель, а где стоит реализовать интерфейс IDisposable?<br>
<br>
Последний вопрос был задан шутки ради.  Как дальше мы с Вами увидим, завершитель всегда стоит использовать в связке с реализацией интерфейса IDisposable. Для тех, кто смог на первые четыре вопроса ответить положительно, а пятый вызвал у него бурю негодования и возмущения, предлагаю заняться более полезным занятием, чем чтение данного руководства.  Остальным же, кто все-таки решился  продолжить чтение или не смог утвердительно ответить на предлагаемые вопросы, предлагаю вместе детально рассмотреть  те проблемы, которые возникают у программиста при работе с ресурсами в наших программах,  выяснить причины возникновения этих проблем, а самое главное найти рецепт их решения. <br>
С самого начала моего знакомства с платформой .NET меня со страниц всех без исключения учебников  безостановочно преследует тезис о том, что автоматический сбор мусора есть панацея от всех бед, связанных с освобождением используемых программой  ресурсов. Но так ли это? Не дает ли это нам ложного ощущения,  что достаточно создать объект, использовать его,  а  сборщик мусора, как всегда отлично, выполнит всю черновую работу по освобождению ресурсов? В подавляющем большинстве случаев так и будет. Сборщик мусора прекрасно удалит все ненужные объекты, которые размещались в памяти нашей программы.  А как же неуправляемые ресурсы? Как же потоки операционной системы, объекты GDI,  файлы и порты, соединения с базой данных? Ответ на этот вопрос, вероятно, знает каждый из Вас, их освобождение ложится на плечи самих программистов, то есть это и есть наша с Вами непосредственная обязанность.  Следовательно и для нас с Вами найдется работа :) Каждый тип, оперирующий  ресурсами,  которые не могут быть освобождены сборщиком мусора, обязан предоставить нам с Вами механизм для их освобождения. В рамках платформы .NET этим механизмом обычно является реализация интерфейса  IDisposable,  который объявляет единственный метод Dispose, посредством вызова которого мы с Вами явно указываем объекту на то, что ему следует освободить неуправляемые  ресурсы, которые он задействовал.  Повторюсь, все объекты, которые используют неуправляемые ресурсы, обязаны предоставить механизм по их освобождению, обычно посредством реализации интерфейса  IDisposable и предоставлению нам с Вами общедоступного метода Dispose.  Из этого следует более чем очевидный вывод: если вы сами пишете тип, который явно или неявно оперирует неуправляемыми ресурсами, он также обязан предоставить клиенту возможность освободить занимаемые им  ресурсы. Но можем ли мы с Вами гарантировать, что все клиенты нашего с Вами типа воспользуются методом Dispose? Мне бы хотелось верить, что это так, но к сожалению... Но не все так безнадежно :). Мы можем застраховаться на этот случай путем реализации завершителя в нашем типе. Что такое завершитель? Это специальный метод, который реализует наш тип, посредством которого сборщик мусора  сможет выполнить освобождение неуправляемых ресурсов.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">public class MyClass</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// завершитель</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;~MyClass()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// освобождаем неуправляемые ресурсы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
<br>
Как видите объявление завершителя подобно объявлению конструктора типа, но с добавлением перед именем значка тильда(~). Думаю разработчики со стажем программирования на С++ могут сказать, что объявление завершителя аналогично  объявлению деструктора, и это так.  Тем не менее есть одно существенное отличие от языка С++, время вызова завершителя не определено (недетерминировано). Следовательно, мы не можем рассчитывать на то, что код по освобождению ресурсов выполнится непосредственно по выходу объекта из области видимости или вызова завершителя.  Так  когда же он отработает? В момент, когда подсистема сбора мусора инициирует уборку, сборщик мусора поступает следующим образом: он удаляет из памяти все объекты, у которых отсутствует завершитель.  Далее  для объектов с завершителем он создает отдельный поток, в котором создает очередь, куда помещает объекты, которые реализовали завершитель, и требуют очистки.  Далее в порядке очередности сборщик мусора последовательно вызывает  завершители для всех объектов, которые в ней находятся. Следует подчеркнуть, что их освобождение происходит в отдельном потоке, и окончание освобождения неуправляемых ресурсов не обязательно совпадает со временем окончания сбора для обычных объектов.  Более того, только после отработки завершителя объект превращается в мусор, который будет убран при следующем проходе сборщиком. Исходя из этого, мы должны теперь для себя провести четкую грань между реализацией IDisposable и реализацией завершителя. Первый предоставляет клиенту класса  механизм по явному освобождению ресурсов  посредством общедоступного метода Dispose, второй страхует нас с Вами от нерадивых программистов, которые по тем или иным причинам забывают вызвать Dispose для нашего типа явно.  А значит более чем очевидно, что правильный путь - это реализация интерфейса IDisposable и завершителя в связке. <br>
И так правильный путь найден, но какие проблемы порождает написание такого кода? Попробуем ответить на несколько вопросов. <br>
1. Что произойдет, если классы наследники захотят переопределить работу завершителя или реализовать IDisposable, согласно собственным потребностям? <br>
2. Как производный класс решит, освобождать ли ресурсы базового типа и то, как это следует реализовать? <br>
Очевидно, следует уведомить об этом базовый класс, иначе последствия такого неуведомления предсказуемы - ресурсы, используемые базовым типом, останутся неочищенными. Существует еще одна дилемма: код, реализуемый методом Dispose, обычно полностью или частично дублируется завершителем. Вот здесь нам на помощь и приходит стандартная модель очистки ресурсов. С ее помощью мы избавляемся и от дублирования кода, и предоставляем классам-наследникам возможность определять собственный механизм освобождения ресурсов, в совокупности с возможностью освобождать ресурсы базового класса. Эта модель реализуется посредством перегрузки метода Dispose следующим образом:<br>
protected virtual void Dispose(bool isDisposing) <br>
Как видно из прототипа, метод объявляется защищенным, а  следовательно, он не предназначен для клиента нашего класса, он необходим нашему типу и типам наследникам. Наш тип будет использовать его в ответ на непосредственный вызов клиентом метода Dispose() или вызов завершителя инфраструктурой сбора  мусора.  Обратите внимание на то, что метод виртуальный, это позволит классам-потомкам переопределить поведение метода с учетом собственных потребностей, параллельно вызывая базовую реализацию метода для освобождения ресурсов класса-предка. Думаю, самые любопытные уже горят желанием узнать: зачем потребовался параметр типа bool? Все очень просто, если завершитель предназначен для освобождения неуправляемых ресурсов, то в методе Dispose зачастую реализуют механизм по освобождению управляемых ресурсов. Вы удивлены? Когда-то я тоже был удивлен. Чтобы понять суть происходящего, нужно хорошо разбираться в тонкостях некоторых процессов, которые происходят при сборке мусора на платформе .NET. Предположим, что наш тип является подписчиком на некоторое событие, в котором он заинтересован. События на платформе .NET являются сильными двунаправленными ссылками. То  есть класс, подписавшийся на событие, не может быть освобожден раньше, чем будет освобожден класс, который генерирует события. Верно так же и обратное: класс, который генерирует событие,  не может быть утилизирован подсистемой сборки мусора, пока он имеет хоть одного «живого» подписчика. Возникает дилемма, которая может быть разрешена исключительно с помощью механизма отписки от событий получателем. Именно поэтому код, отписывающийся от событий, следует также помещать в реализацию метода Dispose.  Итак, в общем виде метод Dispose должен вызываться с параметром true для очистки по требованию клиентом и с параметром false при вызове завершителя. Основываясь на этом параметре, перегруженный метод Dispose принимает решение: стоит ли освобождать управляемые ресурсы (не управляемые ресурсы освобождаются в не зависимости от переданного параметра). <br>
Давайте посмотрим на реализацию IDisposable в  нашем типе:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">public class MyClass : IDisposable</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;~MyClass()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dispose(false);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;public void Dispose()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dispose(true);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GC.SuppressFinalize(this);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
После вызова перегруженной версии Dispose с параметром true, вызывается метод SuppressFinalize, который говорит подсистеме сборки мусора буквально следующие: «Объект был осовобожден явно, вызов завершителя для него более не требуется». По сути мы подавляем вызов завершителя для нашего типа. <br>
	Остался последний нерешенный нами вопрос, что будет, если пользователь обратиться к методу Dispose несколько раз? Возможно ничего, а возможно это приведет к ошибке времени выполнения, поэтому мы перестраховываемся и добавляем в наш тип булеву переменную, которая сигнализирует, что наш тип уже был очищен. Ниже приводится шаблон реализации IDisposable в нашем типе:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">public class MyClass : IDisposable</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;private bool _disposed = false;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// завершитель</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;~MyClass()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dispose(false);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// очищаем ресурсы, после чего подавляем</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// вызов завершителя</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;public void Dispose()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dispose(true);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GC.SuppressFinalize(this);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;protected virtual void Dispose(bool isDisposing)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// если метод уже вызывался,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// то не стоит выполнять очистку дважды</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (_desposed)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (isDisposing)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//освобождаем управляемые ресурсы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// особождение неуправляемых ресурсов</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//установим флажок, что метод уже выполнялся</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_disposed = true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
<br>
Шаблон выше является примером реализации стандартной модели по освобождению ресурсов и должен применяться Вами при конструировании собственных типов. В заключение хотелось бы дать несколько советов. Все общедоступные методы вашего типа не должны выполняться после вызова метода клиентом метода Dispose(), это легко реализовать путем проверки переменной _desposed в теле метода. В случае если объект уже был освобожден, необходимо сгенерировать исключение ObjectDisposed. Также в коде, приведенном выше, переменная _disposed умышленно сделана приватной. Это заставляет производные типы добавлять собственный флаг завершения, и ошибки, которые могут возникать при освобождении объекта, не распространяются по иерархии наследования. Думаю, что также уместным будет продемонстрировать шаблон для класса наследника:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">public class DirevedClass : MyClass</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;private bool _isDisposed = false;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;protected override void Dispose(bool isDisposing)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (_isDisposed)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (isDisposing)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// освобождаем управляемые ресурсы</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// освобождаем неуправляемые ресурсы</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// заметим, что подавление завершителя делегируется базовому типу</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// при этом производный тип вызывает очистку базового класса</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;base.Dispose(isDisposing);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_isDisposed = true;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div></ol></div></div></div></div><br>
<br>
До новых встреч. :)]]></description>
        <author>juice</author>
        <category>.NET FAQ</category>
      </item>
	
      </channel>
      </rss>
	