Используется ли Try-finally для использования по разумным причинам по тем же причинам, что и Try-Catch?

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

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

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

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

Деструктор С# вызывается, когда объект представляет собой сбор мусора, за исключением нескольких пограничных случаев (если приложение закрывается, поток финализатора становится настолько длинным, после чего он просто заканчивается). Но это означает, что вы не знаете, когда это будет вызвано. Может быть, задолго до того, как объект получит сбор мусора. Итак, вы правы, это плохая идея.

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

Ответ 6

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

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

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