Подрывная деятельность имеет очень низкий барьер для доступа.
TortoiseSVN является свободным клиентом и интегрируется в Ваш проводник - т.е. в меню щелчка правой кнопкой мыши.
репозиторий может быть просто каталогом где-нибудь на Вашем ПК или на сетевом диске. Поддержка просто означает архивировать этот каталог
существует несколько плагинов к Visual Studio для Подрывной деятельности, , AnkSvn является тем, который я использовал, это свободно и интегрируется приятно (т.е. это будет умно о перемещении и удалении файлов и т.д.)
, Подрывная деятельность является хорошим выбором для одного разработчика.
Обновление:
Начиная с этого сообщения, я использовал Подвижный. Это - Распределенный SVN. 'Распределенный' аспект не может быть непосредственно полезен для единственного разработчика, однако это лучше в слиянии и несколько быстрее. Существует также свободный и хороший клиент расширения Windows Explorer - черепаха Hg .
Так, таким образом, если Вы - вид человека, который будет работать над многими ответвлениями сразу (выполнение скачков и т.д.) или если бы Вы работаете над несколькими ПК сразу и хотели бы полный офлайновый доступ к истории регистрации на обоих, тогда Подвижный . Если Вы просто хотите простое отслеживание и хорошо доказанный и легкий понять решение, то Подрывная деятельность .
Да, вы ВСЕГДА реализуете IDisposable, если управляете одноразовыми объектами. ВСЕГДА . Ваш код не сломается, если вы этого не сделаете, но он лишает смысла одноразовые объекты, если вы этого не сделаете.
Общее правило оптимизации сборки мусора:
Эти правила могут быть отклонены или проигнорированы, если вы пишете приложение для себя, но при распространении кода другим вы должны быть профессионалом и следовать правилам.
Логика здесь в том, что когда вы управляете памятью вне поля зрения GC, механизм GC не может должным образом управлять использованием вашей памяти. Например, в куче .NET у вас может быть только 4-байтовый указатель, но в неуправляемой области у вас может быть 200 МБ памяти. Механизм GC не будет пытаться собрать их, пока у вас не будет несколько десятков, потому что все, что он видит, - это несколько байтов; в то время как в реальном мире это очень похоже на утечку памяти.
Таким образом, правило заключается в том, что неуправляемая память должна освобождаться немедленно, когда вы закончите ее использовать (цепочка IDisposable делает это за вас), а управляемая память получает освобождаются механизмом сборки мусора всякий раз, когда он к нему приближается.
но в неуправляемой стране можно указать 200 МБ памяти. Механизм GC не будет пытаться собрать их, пока у вас не будет нескольких десятков, потому что все, что он видит, - это несколько байтов; в то время как в реальном мире это очень похоже на утечку памяти.Таким образом, правило заключается в том, что неуправляемая память должна освобождаться немедленно, когда вы закончите ее использовать (цепочка IDisposable делает это за вас), а управляемая память получает освобождается механизмом сборщика мусора всякий раз, когда он к нему приближается.
но в неуправляемой стране можно указать 200 МБ памяти. Механизм GC не будет пытаться собрать их, пока у вас не будет несколько десятков, потому что все, что он видит, - это несколько байтов; в то время как в реальном мире это очень похоже на утечку памяти.Таким образом, правило заключается в том, что неуправляемая память должна освобождаться немедленно, когда вы закончите ее использовать (цепочка IDisposable делает это за вас), а управляемая память получает освобождаются механизмом сборки мусора всякий раз, когда он к нему приближается.
Вы должны сделать это, поскольку это единственный способ для пользователя вашего класса убедиться, что внутренний ресурс правильно удален.
Однако шаблон, используемый для Dispose () в этом случае может немного отличаться от того, что обычно написано, поскольку вам не нужно различать неуправляемые и управляемые ресурсы (ваш инкапсулированный ресурс всегда рассматривается как «управляемый» ресурс).
Я написал подробное сообщение в блоге по этой конкретной теме - Инкапсуляция IDisposable ресурсов .
Да, ваш класс должен быть IDisposable, если ему нужно избавиться от любых объектов, которые он использует. Примером этого является StreamReader. Он реализует IDisposable, чтобы можно было удалить связанный с ним объект потока.
Если я правильно понял ваш вопрос, у вас есть класс, который использует 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;
}
Существует два различных сценария:
Во втором случае ваш объект отвечает за задействованные ресурсы, поэтому ваш объект должен реализовывать IDisposable, и при удалении вы должны избавиться от объекта вы создали.
Ваш DbConnection подпадает под этот второй случай, поэтому да, ваш объект должен реализовать IDisposable, а затем удалить соединение.
В первом случае вам необходимо выбрать следующие три решения:
Это было много текста, поэтому позвольте мне резюмировать:
Есть также третий случай, который не звучит так, как будто у вас есть, но, тем не менее.
В случае, когда вы создаете, используете и отбрасываете, объект локально, внутри одного метода, не передавая его и не сохраняя в полях класса, вместо этого вы используете оператор using
, например:
using (IDbConnection conn = ....())
{
}
Это, безусловно, лучшая практика, особенно при работе с тяжелыми / неуправляемыми объектами.
Изменить: Лучшая практика, но не обязательно.
Поскольку мы никогда не знаем, когда объект будет собран сборщиком мусора, мы используем интерфейс IDisposable, чтобы иметь возможность намеренно освободить неуправляемые ресурсы до того, как объект будет собран сборщиком мусора. Если одноразовый объект не удален перед сбором, его ресурсы могут не высвободиться до выхода из домена приложения. Это почти неписаное правило, согласно которому каждый объект, имеющий ссылку на объект IDisposable, должен быть сам IDisposable и вызывать метод Dispose для своих ссылок IDisposable в собственном методе Dispose.
Конечно, вы можете убрать большую часть затрат на (повторную) реализацию IDisposable и получить что-то довольно близкое к детерминированной финализации объектов в управляемой куче, если вы используете C ++ / CLI . Это часто (я нахожу) упускаемый из виду аспект языка, который многие люди, кажется, отправляют в корзину «только для кода клея».
Когда вы предоставляете явное управление с помощью Dispose, вы должны обеспечить неявную очистку с помощью метода Finalize. Finalize обеспечивает резервную копию для предотвращения постоянной утечки ресурсов, если программист не может вызвать Dispose.
Я думаю, что лучший способ реализовать это - использовать комбинацию методов Dispose и Finalize. Вы можете найти больше Здесь .