Когда я должен использовать IDisposable, разве когда-либо неправильно использовать его? Что относительно Располагают Объединение в цепочку?

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

Когда я ДОЛЖЕН использовать IDisposable? Только, когда у меня есть неуправляемые ресурсы?

Что изменения расположить шаблона там и почему они варьируются?

Что такое общие неуправляемые ресурсы, о которых я должен знать?

Это когда-нибудь неправильно или вводящий в заблуждение для реализации IDisposable?

Должен Расположить вызовы когда-нибудь быть объединенным в цепочку вместе, или мы должны полагаться на использование операторов? Например:

public Dispose(bool disposing)
{
  ...
  this.SomeDependency.Dispose;
}
9
задан Firoso 31 July 2010 в 11:32
поделиться

2 ответа

Вау. Здесь много вопросов!

Когда СЛЕДУЕТ использовать IDisposable? Только когда у меня есть неуправляемые ресурсы?

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

using(var timer = new MyTimer())
{
    //do some stuff
}

В этом случае вызов Dispose не обязательно освобождает какие-либо ресурсы, это просто удобный и последовательный (два ключа для шаблона!) Способ сказать таймеру «ОК» , Я с тобой покончил », и таймер может остановить отсчет времени и, возможно, записать время где-нибудь.

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

Какие существуют варианты шаблона удаления и почему они различаются?

Есть только один реальный «конкретный» тип реализации IDisposable , о котором я знаю - шаблон Finalize / Dispose:

public class MyClass : IDisposable
{
   void IDisposable.Dispose() 
   {
     Dispose(true);
     GC.SuppressFinalize(this); 
   }

   protected virtual void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   ~MyClass()
   {
      Dispose(false);
   }
}

Какие общие неуправляемые ресурсы мне следует знать?

Все, что реализует IDisposable , особенно в библиотеках .NET, должно иметь дескрипторы для неуправляемых ресурсов и должно быть удалено. Обычно через них вы получаете доступ только к неуправляемым ресурсам. Если нет, то вы знаете - обычно строят драйвер или что-то в этом роде.

Реализовать IDisposable когда-либо неправильно или вводить в заблуждение?

Злоупотреблять им может быть бессмысленно, но не вредно.

Должны ли вызовы Dispose объединяться в цепочку

Класс должен удалять только те IDisposables, которые он создает внутри. Если у него есть одноразовые зависимости, которые были внедрены или находятся за пределами класса, вы никогда не должны избавляться от них.

6
ответ дан 3 November 2019 в 01:52
поделиться

Есть две основные вещи, которые я написал относительно IDisposable, и я рекомендую вам прочитать хотя бы первую: How to Implement IDisposable and Finalizers - 3 Easy Rules (у меня также есть другие записи в блоге на эту тему) и IDisposable - What Your Mother Never Told You about Resource Deallocation.

Когда ДОЛЖЕН использоваться IDisposable? Только когда у меня есть неуправляемые ресурсы?

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

Обратите внимание, что все остальные мои ответы (и ссылки) обсуждают IDisposable в контексте освобождения ресурсов. Они не затрагивают RAII.

Какие существуют разновидности шаблона dispose и почему они различаются?

Шаблон Microsoft является наиболее известным. Он позволяет освобождать неуправляемые и управляемые ресурсы и допускает наследование. Я предпочитаю более простой шаблон, описанный в моем блоге (3 простых правила), которому Microsoft фактически следует с .NET 2.0.

О каких общих неуправляемых ресурсах я должен знать?

Я предпочитаю иметь один класс IDisposable для каждого типа неуправляемых ресурсов (подобно SafeFileHandle от Microsoft). Таким образом, каждый раз, когда вы добавляете тип неуправляемого ресурса в свою программу/библиотеку, вам придется обрабатывать его только один раз.

Тогда возникает вопрос: "Какие классы я должен утилизировать?", на который есть простой ответ: "все классы, реализующие IDisposable."

Разве реализация IDisposable может быть неправильной или вводить в заблуждение?

Нет. Пустая реализация IDisposable - это всегда вариант. Вы должны рассмотреть возможность добавления IDisposable в интерфейсы или базовые классы, если вы думаете, что реализация может их использовать. Это вопрос проектирования, о котором я подробнее рассказываю в статье What Your Mother Never Told You.

Следует ли вообще связывать вызовы Dispose вместе или лучше полагаться на операторы using?

Обычно Dispose вызывает Dispose для всех объектов-членов, которыми он владеет. Подробнее см. в моем втором правиле в блоге.

4
ответ дан 3 November 2019 в 01:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: