Используется ли Try-Наконец для экономного использования по тем же причинам, что и Try-Catch? - PullRequest
11 голосов
/ 04 января 2009

Я только что закончил читать эту статью о преимуществах и недостатках исключений, и я согласен с мнением, что блоки Try-Catch не должны использоваться для "нормального" управления потоком управления (не используйте их как гото). Тем не менее, один автор высказал (хорошие) замечания по поводу ремонтопригодности и особенно производительности, которые заставили меня задуматься о том же в блоках Try-finally.

Я окружаю каждое Событие открытия соединения в моем приложении ASP.NET с помощью Try, чтобы я мог быть уверен, что Соединение завершено в Окончании. Утечка соединений, очевидно, НЕ является хорошей вещью в веб-приложении, и я сомневаюсь, что я бы изменил эту практику, но что вы думаете?

Примечание: у меня есть соединения, завернутые в DAL, и я могу закрывать соединения, когда вызывается деструктор объекта, но мне это кажется отрывочным. Насколько я знаю, вы не можете рассчитывать на вызов деструктора в случае исключения. Я не прав?

Ответы [ 6 ]

19 голосов
/ 04 января 2009

Вам не нужно избегать шаблонов кодирования try {} ... finally {}. Но что касается ваших соединений, так как они IDisposable, используйте вместо этого «using», так как он делает для вас то же самое, что и более длинный и более громоздкий блок try / finally.

3 голосов
/ 04 января 2009

В bad повсеместном использовании блока try-catch заключается в том, что при использовании исключения вы потенциально можете скрыть плохой код. Try-finally (без перехвата) не скрывает исключения, но обеспечивает гарантии выполнения кода. В вашем случае вы можете ожидать определенные типы исключений даже от правильно сформированных команд SQL (например, попытка вставить дублирующую строку), и, таким образом, я думаю, что использование finally вполне оправдано. Это предполагает, что вы, как и я, чувствуете, что соединения должны быть кратковременными и открываться / закрываться при использовании, а не в течение срока действия вашего DAL.

РЕДАКТИРОВАТЬ : Я бы рекомендовал @Dave Markle. Блок использования намного более элегантен и семантически эквивалентен. Единственный раз, когда я предпочитаю использовать метод try-finally, это избегать многократных вложенных операций в пользу одной попытки try-finally.

2 голосов
/ 04 января 2009

Используйте Try / Наконец, где это имеет смысл, не пытайтесь оптимизировать это, пока у вас не возникнет проблема, вызванная этим.

Сказав это, Try / Наконец не так дорого, как исключения. Конечно, они не бесплатны, но бросить и поймать исключение дороже, чем блок Try / finally.

«Деструктор» в .NET вызывается, когда объект подвергается сборке мусора, что означает, что может пройти много времени, прежде чем он будет вызван. Используйте шаблон Dispose для реализации детерминированного удаления ресурсов.

1 голос
/ 04 января 2009

Деструктор C # вызывается, когда объект собирается сборщиком мусора, за исключением нескольких пограничных случаев (если приложение закрывается, поток финализатора становится слишком длинным, после чего он просто завершается). Но это означает, что вы не знаете , когда он будет вызван. Это может занять много времени, прежде чем объект будет собирать мусор. Так что вы правы, это плохая идея.

Однако, попытка / окончание, как правило, тоже бессмысленна, потому что блок using будет достигать того же результата более элегантно.

1 голос
/ 04 января 2009

Я полагаю, что гораздо лучше обернуть соединение в оператор using (при условии, что соединение реализует IDisposable). Метод dispose проверит состояние вашего соединения и при необходимости закроет.

0 голосов
/ 04 января 2009

Как уже отмечали другие, try-finally редко требуется из-за наличия конструкции using в C #. Я все еще верю, что модель является шагом назад по сравнению с RAII в C ++ - причина в том, что бремя все еще лежит на клиентском коде, который нужно помнить, чтобы использовать use (точно так же, как они должны были бы помнить использовать try-finally). И хотя использование более кратко, чем try-finally, оно все равно кажется излишне многословным, если вы привыкли к C ++, особенно когда вы получаете несколько уровней вложенности.

Я написал запись в блоге о том, как смягчить это некоторое время назад:

http://www.levelofindirection.com/journal/2009/9/24/raii-and-readability-in-c.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...