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()
メソッドに対して。Usingブロックは_try/finally
_ブロックにすぎないため、return
ブロック内でusing
を呼び出すことは完全に安全です。
上記の例では、return true
の後、スコープは破棄され、値が返されます。 _return false
_、およびscope.Complete()
はnotが呼び出されます。ただし、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()
に到達する方法がないため、トランザクションはnever commitすることに注意してください。
それは問題ありません-finally
句(using
句の閉じ中かっこが内部で行うこと)は、どのようにスコープが去っても常に実行されます。
ただし、これはfinallyブロック(using
を使用する場合は明示的に設定できない)にあるステートメントにのみ当てはまります。したがって、あなたの例では、scope.Complete()
が呼び出されることはありません(コンパイラーが到達不能コードについて警告することを期待しています)。
scope.Completeは、return
の前に必ず呼び出す必要があります。コンパイラは警告を表示し、このコードは呼び出されません。
return
自体について-はい、using
ステートメント内で呼び出しても安全です。を使用して、舞台裏で最終的にブロックし、最終的にブロックを実行するように変換します。
一般的に、これは良いアプローチです。ただし、あなたの場合、scope.Complete()
を呼び出す前に戻ると、TransactionScopeが破棄されます。デザインに依存します。
そのため、このサンプルでは、Complete()は呼び出されず、IDisposableインターフェイスを継承していると想定してスコープが破棄されます。
scope.Complete()
が確実に呼び出されるようにするには、try/finally
でラップします。 dispose
は、代替のtry/finally
ブロックであるusing
でラップしているために呼び出されます。
using(var scope = new TransactionScope())
{
try
{
// my core logic
return true; // if condition met else
return false;
}
finally
{
scope.Complete();
}
}
指定した例には問題があります。 scope.Complete()
は呼び出されません。第二に、return
ステートメント内でusing
ステートメントを使用することはお勧めできません。以下を参照してください。
using(var scope = new TransactionScope())
{
//have some logic here
return scope;
}
この単純な例では、ポイントはそれです。ステートメントの使用が終了すると、scope
の値はnullになります。
したがって、ステートメントを使用して内部に戻らない方が良いでしょう。
この例では、scope.Complete()は実行されません。ただし、returnコマンドは、スタックに割り当てられているすべてのものをクリーンアップします。 GCは、参照されていないすべてを処理します。したがって、GCで取得できないオブジェクトがない限り、問題はありません。