IDisposable должен быть применен cascadingly?

Подрывная деятельность имеет очень низкий барьер для доступа.

TortoiseSVN является свободным клиентом и интегрируется в Ваш проводник - т.е. в меню щелчка правой кнопкой мыши.

репозиторий может быть просто каталогом где-нибудь на Вашем ПК или на сетевом диске. Поддержка просто означает архивировать этот каталог

существует несколько плагинов к Visual Studio для Подрывной деятельности, , AnkSvn является тем, который я использовал, это свободно и интегрируется приятно (т.е. это будет умно о перемещении и удалении файлов и т.д.)

, Подрывная деятельность является хорошим выбором для одного разработчика.

Обновление:

Начиная с этого сообщения, я использовал Подвижный. Это - Распределенный SVN. 'Распределенный' аспект не может быть непосредственно полезен для единственного разработчика, однако это лучше в слиянии и несколько быстрее. Существует также свободный и хороший клиент расширения Windows Explorer - черепаха Hg .

Так, таким образом, если Вы - вид человека, который будет работать над многими ответвлениями сразу (выполнение скачков и т.д.) или если бы Вы работаете над несколькими ПК сразу и хотели бы полный офлайновый доступ к истории регистрации на обоих, тогда Подвижный . Если Вы просто хотите простое отслеживание и хорошо доказанный и легкий понять решение, то Подрывная деятельность .

14
задан Johannes Rudolph 22 September 2009 в 17:50
поделиться

9 ответов

Да, вы ВСЕГДА реализуете IDisposable, если управляете одноразовыми объектами. ВСЕГДА . Ваш код не сломается, если вы этого не сделаете, но он лишает смысла одноразовые объекты, если вы этого не сделаете.

Общее правило оптимизации сборки мусора:

  • Любой класс, который управляет объектами, не управляемыми сборщиком мусора, должен реализовывать финализатор (и, как правило, также должен реализовывать IDisposable). Именно отсюда обычно берутся одноразовые классы «верхнего уровня» - они обычно управляют HANDLE для окна, сокета, мьютекса или чего-то еще.
  • Любой класс, который создает экземпляр члена IDisposable, должен реализовывать сам IDisposable и должным образом Dispose () его составляющих.
  • Любая функция, которая создает экземпляр объекта IDisposeable, должна правильно использовать Dispose () после его использования. Не позволяйте этому просто выпадать из области видимости.

Эти правила могут быть отклонены или проигнорированы, если вы пишете приложение для себя, но при распространении кода другим вы должны быть профессионалом и следовать правилам.

Логика здесь в том, что когда вы управляете памятью вне поля зрения GC, механизм GC не может должным образом управлять использованием вашей памяти. Например, в куче .NET у вас может быть только 4-байтовый указатель, но в неуправляемой области у вас может быть 200 МБ памяти. Механизм GC не будет пытаться собрать их, пока у вас не будет несколько десятков, потому что все, что он видит, - это несколько байтов; в то время как в реальном мире это очень похоже на утечку памяти.

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

но в неуправляемой стране можно указать 200 МБ памяти. Механизм GC не будет пытаться собрать их, пока у вас не будет нескольких десятков, потому что все, что он видит, - это несколько байтов; в то время как в реальном мире это очень похоже на утечку памяти.

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

но в неуправляемой стране можно указать 200 МБ памяти. Механизм GC не будет пытаться собрать их, пока у вас не будет несколько десятков, потому что все, что он видит, - это несколько байтов; в то время как в реальном мире это очень похоже на утечку памяти.

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

10
ответ дан 1 December 2019 в 12:13
поделиться

Вы должны сделать это, поскольку это единственный способ для пользователя вашего класса убедиться, что внутренний ресурс правильно удален.

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

Я написал подробное сообщение в блоге по этой конкретной теме - Инкапсуляция IDisposable ресурсов .

3
ответ дан 1 December 2019 в 12:13
поделиться

Да, ваш класс должен быть IDisposable, если ему нужно избавиться от любых объектов, которые он использует. Примером этого является StreamReader. Он реализует IDisposable, чтобы можно было удалить связанный с ним объект потока.

6
ответ дан 1 December 2019 в 12:13
поделиться

Если я правильно понял ваш вопрос, у вас есть класс, который использует DbConnection. Вы хотите убедиться, что DbConnection правильно удален, когда вы закончите работу с ним или когда ваш класс удален. Есть несколько способов добиться этого.

Если вы используете соединение с базой данных в качестве локальной переменной в методе, вы можете использовать оператор using () {}.

using (SqlConnection sqlConnection = new SqlConnection ( connStr))
{
... здесь можно сделать что-нибудь с подключением
}

Оператор using () {} автоматически вызывает Dispose () для объектов, объявленных в (). (Также требуется, чтобы объекты, объявленные в (), реализовывали IDisposable, чтобы гарантировать, что они могут быть удалены)

Если вместо этого вы работаете с DbConnection как с частной переменной, которая инициализируется во время создания объекта или каким-либо другим методом инициализации, тогда вы, вероятно, захотите самостоятельно реализовать IDisposable, а затем вызвать _dbConnection.Dispose () в своем методе Dispose (). Таким образом, когда ваш объект будет удален, объект подключения к базе данных также будет удален.

открытый класс MyDALObj: IDisposable
{

общедоступный MyDalObj ()
{
... создать объект _dbConn ...
}

public void Dispose ()
{
_dbConn.Dispose ();
}

частное соединение DbConnection _dbConn;
}

3
ответ дан 1 December 2019 в 12:13
поделиться

Существует два различных сценария:

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

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

Ваш DbConnection подпадает под этот второй случай, поэтому да, ваш объект должен реализовать IDisposable, а затем удалить соединение.

В первом случае вам необходимо выбрать следующие три решения:

  1. Ваш объект ссылается только на внешний объект. Ваш объект не должен избавляться от этого внешнего объекта. Вам не нужно реализовывать IDisposable для этого случая (то есть для этого конкретного объекта, если вы также внутренне создаете одноразовый объект, вы вернетесь ко второму случаю выше).
  2. Ваш объект берет на себя ответственность за внешний объект. В этом случае вы возвращаетесь ко второму случаю, даже если ваш объект не был тем, который строил этот внешний объект. Здесь вы реализуете IDisposable и удаляете данный объект.
  3. Вы реализуете способ, которым внешний мир сообщает вам, какое из первых двух решений выбрать. Например, конструктору может быть дано соединение и логический аргумент (или, в идеале, значение перечисления), который сообщает конструктору, владеет ли теперь ваш объект предоставленным соединением. Здесь также нужно реализовать IDisposable, но в методе Dispose вам нужно проверить право собственности и избавиться от предоставленного соединения, только если оно вам принадлежит.

Это было много текста, поэтому позвольте мне резюмировать:

  1. Объекты, которыми вы владеете, вам необходимо избавиться.
  2. Объекты если вы этого не сделаете, вы не избавитесь.

Есть также третий случай, который не звучит так, как будто у вас есть, но, тем не менее.

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

using (IDbConnection conn = ....())
{
}
2
ответ дан 1 December 2019 в 12:13
поделиться

Это, безусловно, лучшая практика, особенно при работе с тяжелыми / неуправляемыми объектами.

Изменить: Лучшая практика, но не обязательно.

0
ответ дан 1 December 2019 в 12:13
поделиться

Поскольку мы никогда не знаем, когда объект будет собран сборщиком мусора, мы используем интерфейс IDisposable, чтобы иметь возможность намеренно освободить неуправляемые ресурсы до того, как объект будет собран сборщиком мусора. Если одноразовый объект не удален перед сбором, его ресурсы могут не высвободиться до выхода из домена приложения. Это почти неписаное правило, согласно которому каждый объект, имеющий ссылку на объект IDisposable, должен быть сам IDisposable и вызывать метод Dispose для своих ссылок IDisposable в собственном методе Dispose.

0
ответ дан 1 December 2019 в 12:13
поделиться

Конечно, вы можете убрать большую часть затрат на (повторную) реализацию IDisposable и получить что-то довольно близкое к детерминированной финализации объектов в управляемой куче, если вы используете C ++ / CLI . Это часто (я нахожу) упускаемый из виду аспект языка, который многие люди, кажется, отправляют в корзину «только для кода клея».

0
ответ дан 1 December 2019 в 12:13
поделиться

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

Я думаю, что лучший способ реализовать это - использовать комбинацию методов Dispose и Finalize. Вы можете найти больше Здесь .

0
ответ дан 1 December 2019 в 12:13
поделиться
Другие вопросы по тегам:

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