55

それを使用することが適切である状況はありますかtry-finallyなしのブロックcatchブロック?


  • MSDNでは、を参照してくださいtry-finally(C#リファレンス)。この記事では、の組み合わせの使用について言及していることに注意してください。tryそしてfinally"としてやってみる ステートメント」 - DavidRR

11 답변


88

あなたはそれの後にいくつかの行動が起こるのを確実にするためにそれを使うでしょうtryコンテンツまたは例外が発生したが、その例外を消費したくない場合

明確にするために、これは例外を隠しません。のfinally例外がコールスタックに伝播される前にblockが実行されます。

あなたが使用するときにも誤ってそれを使用するだろうusingこれはキーワードにコンパイルされるためです。try-finally(正確な変換ではありませんが、議論のためにそれは十分に近いです)。

try
{
    TrySomeCodeThatMightException();
}
finally
{
    CleanupEvenOnFailure();
}

で実行中のコードfinally実行することは保証されていませんが、それが保証されていない場合はかなり縁があります - それを思い出すことすらできません。私が覚えているのは、あなたがそのような場合であれば、可能性は非常に高いです。finallyあなたの最大の問題ではありません:-)だから基本的には汗をかいてはいけません。

Tobiasから更新: finallyプロセスが強制終了されると実行されません。

水田からの更新: 最後に.net try..finallyブロックで実行されない条件

最もよく見られる例は、コードが失敗してもデータベース接続または外部リソースを破棄することです。

using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
    // Do stuff.
}

にコンパイル何か好きです:

SqlConnection conn;

try
{
    conn = new SqlConnection("");
    // Do stuff.
}
finally
{
    if (conn != null)
        conn.Dispose();
}


  • コード例では+1です。 - Mitch Wheat
  • @AnthonyBlake例外は隠されていません。例外が発生した場合は、finallyを実行してからコールスタックにバックアップします。 - Adam Houldsworth
  • エッジケースについては、プロセスが強制終了された場合(タスクマネージャの「プロセスの終了」や停電などの理由で)、最後に実行されることはありません。 - Nuffin
  • finallyステートメントが起動しないタイミングについての詳細な情報は、プロセスが強制終了されたときだけではありません。stackoverflow.com/questions/111597/… - Paddy
  • そうでない別の明らかなケースすべてfinallyブロックの途中でエラーが発生した場合 - Ben Hocking

5

using同等ですtry-finally。あなただけが使用しますtry-finally中を片付けたいときfinallyそして例外を気にしないでください。

最善のアプローチになります

try
{
   using(resource)
   {
       //Do something here
   }   
}catch(Exception)
{
     //Handle Error
}

そうすることによってさえ呼ばれた一掃using失敗しても、コードは失敗しません。

ときにいくつかの条件がありますfinally実行されません。

  • あればStackOverflowExceptionまたはExecutingEngineException
  • プロセスは外部ソースから強制終了されました。

これがあなたの疑問に答えることを願っています。


2

たとえば、自分で作成してtryブロックで使用するアンマネージリソースがある場合は、finallyブロックを使用してそのリソースを確実に解放できます。 finallyブロックは、tryブロック内で発生したこと(例外など)にかかわらず、常に実行されます。

例えば。 lock(x)ステートメントは本当に

System.Threading.Monitor.Enter(x); 
try { ... } 
finally 
{ 
    System.Threading.Monitor.Exit(x); 
} 

finallyブロックは、排他ロックが解除されていることを確認するために常に呼び出されます。


2

コードを使用したわかりやすい説明:

void MyMethod1()
{
    try
    {
        MyMethod2();
        MyMethod3();
    }
    catch(Exception e)
    {
        //do something with the exception
    }
}


void MyMethod2()
{
    try
    {
        //perform actions that need cleaning up
    }
    finally
    {
        //clean up
    }
}


void MyMethod3()
{
    //do something
}

MyMethod2またはMyMethod3のいずれかが例外をスローした場合は、MyMethod1によってキャッチされます。しかし、MyMethod2のコードはクリーンアップコードを実行する必要があります。例外がMyMethod1に渡される前に、データベース接続を閉じます。

http://forums.asp.net/t/1092267.aspx?Try+without+Catch+but+with+finally+doesn+t+throw+error+Why+no+syntax+error+


  • この'クリーンアップの例saveLogFile()にすることもできます。これは、プログラムの最後に配置する必要があります。 - Vincent

1

どの例外がキャッチされたとしても、あるいは何もキャッチされなかったとしても、ブロックが終了する前に何らかのコードを実行したい場合は、finallyブロックが必要です。たとえば、開いているファイルを閉じることができます。

参照やってみる


1

/ finally:例外を処理したくないが、呼び出されたコードによって例外がスローされたかどうかにかかわらず、何らかのアクションを確実に実行したい場合。


1

次のリンクを見てください。https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause

それはあなたのアプリケーションのアーキテクチャとあなたがそのブロックで実行している操作に依存します。


1

これは、やっとtryを使用したい状況です。通常usingステートメントを使用しますが、リフレクションによってメソッドを呼び出しているため使用できません。

これはうまくいきません

using (objMsg  =  Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO")))
{

}

代わりに使う

           object objMsg = null;
            try
            {
                objMsg
                   = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO"));

                strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public
                        | BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg,
                        new object[] { vxmlRequest.OuterXml });
            }               
            finally
            {
                if (objMsg!=null)
                    ((IDisposable)objMsg).Dispose();
            }


0

私はC#については何も知りませんが、try-finallyを使ってできることなら何でもできるように思われます。使用ステートメント。 C ++にはようやくそのRAIIの結果


0

これは私がいつも(ええと..)使うユースケースです:

int? x; //note the nullable type here!
try
{
    x = int.Parse(someString);
}
catch { } //don't care, let it just be null


0

1.我々はcatchなしでtryブロックを使うことができますが、最後にcatch /を使うべきです。 それらのどれでも。 2. try blockだけは使えません。

リンクされた質問


関連する質問

最近の質問