Я просто хочу знать, безопасно ли/хорошо ли вызывать return
внутри блока using
.
Например.
using(var scope = new TransactionScope())
{
// my core logic
return true; // if condition met else
return false;
scope.Complete();
}
Мы знаем, что в самой последней фигурной скобке dispose()
произойдет отбой. Но что будет в приведенном выше случае, ведь return
выводит управление из заданной области видимости (AFAIK)...
scope.Complete()
?dispose()
.Совершенно безопасно вызывать return
внутри блока using
, поскольку блок using - это просто блок try/finally
.
В приведенном вами примере после возврата true
область видимости будет утилизирована, а возвращаемое значение. return false
, и scope.Complete()
не будет **** вызвана. Однако Dispose
будет вызван независимо от этого, поскольку он находится внутри блока finally.
Ваш код, по сути, аналогичен этому (если это облегчает понимание):
var scope = new TransactionScope())
try
{
// my core logic
return true; // if condition met else
return false;
scope.Complete();
}
finally
{
if( scope != null)
((IDisposable)scope).Dispose();
}
Пожалуйста, имейте в виду, что ваша транзакция никогда не будет зафиксирована, поскольку нет способа добраться до scope.Complete()
, чтобы зафиксировать транзакцию.
Это нормально - клаузы finally
(а именно это делает закрывающая фигурная скобка клаузы using
) всегда выполняются при выходе из области видимости, независимо от того, каким образом.
Однако это справедливо только для операторов, находящихся в блоке finally (который нельзя явно задать при использовании using
). Поэтому в вашем примере scope.Complete()
никогда не будет вызвано (я ожидаю, что компилятор все же предупредит вас о недостижимом коде).
область.В комплекте обязательно должен быть вызван перед возвращение
. Компилятор выдаст предупреждение и этот код никогда не будет вызван.
Что касается "вернуть" себя - да, ее с уверенностью можно назвать его внутри использование
заявление. Используя переведен на попробовать-наконец-то блок За сценой и, наконец, блок должен быть безусловно выполнены.
В целом, это хороший подход. Но в вашем случае, если вы вернетесь до вызова scope.Complete()
, это просто уничтожит TransactionScope. Зависит от вашего дизайна.
Так, в данном примере Complete() не вызывается, а scope утилизируется, предполагая, что он наследует интерфейс IDisposable.
Чтобы убедиться, что масштабы.Полный () будет называться, оберните его попробовать/наконец-то
. В распоряжаться
называется потому, что вы обернуть его с помощьюэто
блок try/наконец-то`.
using(var scope = new TransactionScope())
{
try
{
// my core logic
return true; // if condition met else
return false;
}
finally
{
scope.Complete();
}
}
В примере вы указали, есть проблема, масштабы.Полный () никогда не называют.
Во-вторых, это не хорошая практика, чтобы использовать возвращение
инструкция, используя
отчетность. Обратитесь к следующим:
using(var scope = new TransactionScope())
{
//have some logic here
return scope;
}
В этом простом примере, суть в том, что, значение сфера
будет null при использовании инструкция закончена.
Так что лучше не возвращаться внутрь с помощью заявления.
В этом примере область.Полный() никогда не будет выполняться. Однако, команда возврата будет очистка всего, что назначенные на стек. ГК будет заботиться о все, что неиспользуемая. Так что, если есть объект, который не может быть подобран ГК, нет никаких проблем.