В C ++ вы все равно должны получить менее видимый код обработки ошибок, потому что вы можете оставить большую часть тяжелой работы для исключений.
На мой взгляд, самое основное правило с исключениями (и одно из них чаще всего нарушается) это. Не пытайтесь отлавливать исключения, если у вас нет определенного плана для их обработки.
За исключением исключений, вам не нужно беспокоиться о кодах ошибок, возвращаемых функциями, потому что хорошо разработанные функции будут просто генерировать исключения.
В C типичный сценарий обработки ошибок выглядит следующим образом:
int DoA()
{
if (location == hellInAHandcart)
return ERROR;
else
RETURN OK;
}
int DoB()
{
int err = DoA();
if (err != OK)
return err;
else
return DoSomethingElse1();
}
int DoC()
{
int err = DoB();
if (err != OK)
//Handle My error here in whatever way...
}
В то время как в C ++ ...
void DoA()
{
if (location == hellInAHandcart)
throw Exception("Gone To Hell in a Handcart");
}
void DoB()
{
DoA();
DoSomethingElse1();
}
void DoC()
{
try
{
DoB();
}
catch (Exception &E)
{
// Handle My error here in whatever way...
}
}
В C # вы обычно закрываете соединения сразу после их использования, например:
using(SqlConnection connection = ...)
{
... do something ...
} // connection disposed / closed here
Однако обычно вы будете использовать пул соединений, и все это делает - возвращает соединение с пулом. Таким образом, ваш процесс по-прежнему будет иметь активные соединения с сервером базы данных.
Если вы завершите работу чисто, пул соединений, несомненно, будет очищен, а фактические соединения с базой данных будут закрыты (вы можете проверить это, посмотрев на открытые соединения на сервере базы данных).
Но бывают ситуации (например, вызов Environment.
Если вы специально не закроете соединение, они будут оставаться открытыми до истечения времени ожидания.
Я обнаружил это на собственном опыте в C # несколько раз. Лучшие практики требуют выключения / закрытия ресурсов, которые, как вы знаете, вам больше не понадобятся. Потоки файлового ввода-вывода, подключения к БД и т. Д.
После завершения процесса все связанные ресурсы (включая память, дескрипторы, соединения, ...) будут освобождены.
Обычно в C # вы используете Удалите шаблон / с помощью оператора
для управления ограниченными ресурсами.
В C # неявная очистка выполняется сборщиком мусора, если финализатор реализован в объекте, собираемом сборщиком мусора. Любую очистку неуправляемых ресурсов, таких как подключения к базе данных, можно выполнить с помощью метода Dispose.
Дополнительные сведения см. В этой статье:
Реализация Finalize и Dispose для очистки неуправляемых ресурсов
http: // msdn. microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx[1270 impression
Когда процесс завершается, все файловые дескрипторы, которые он открыл, должны быть освобождены операционной системой. Дескрипторы файлов включают файлы и сокеты, которые обычно охватывают ваши соединения с базой данных.
Все, что вам говорит, это то, что когда ваш клиент завершает работу, его соединения закрываются. Он не сообщает вам, что делает сервер. В зависимости от того, как это написано, вполне возможно, что сервер продолжит держать свои соединения открытыми, ожидание сообщений от клиента, которые никогда не будут получены, или даже попытка отправить данные. В конечном итоге они, вероятно, истекут, но это может быть плохо спланировано. (Это должно быть для приличной СУБД, но может и не быть.) Таким образом, в зависимости от вашей СУБД вам может потребоваться предпринять некоторые шаги, чтобы сообщить серверу, что вы падаете, чтобы он высвободил свои ресурсы.
Если вы работаете с SQL Server, вы можете просмотреть sysprocesses или запустить sp_who2. Я проверил это на своей машине, и соединения действительно закрываются, то есть:
Console.Write("Opening connection");
Console.ReadLine();
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=SeniorMail;Integrated Security=SSPI;");
connection.Open();
SqlCommand command = new SqlCommand("SELECT count(*) from Account", connection);
Console.Write("Running sql");
Console.ReadLine();
int? count = command.ExecuteScalar() as int?;
Console.Write("Now I'll throw an exception");
Console.ReadLine();
int a = 0, b = 1, c = 0;
try
{
c = b / a;
}
catch
{
Environment.Exit(1);
}
Я проверил sp_who2 по обе стороны от «Теперь я вызову исключение», и я вижу, что соединение исчезло после выхода из приложения.
Общее поведение POSIX состоит в том, что при завершении программы все дескрипторы файлов, сетевые соединения и т. Д. Закрываются. Вопрос о том, правильно ли поступает другой конец в данный момент, остается открытым, но если вы используете какую-либо достаточно популярную СУБД, все будет в порядке.
Он должен быть очищен на следующем GC, но, если быть точным, в C # вы можете закрыть соединение на блоке finally обработки структурированных исключений.
try {
// open DB connection
} catch (Exception ex) {
// deal with exception
} finally {
// close and dispose connection
}