5

コンソール アプリケーション内で何らかの理由で、finally ブロックを実行できません。finally ブロックがどのように機能するかをテストするためにこのコードを書いていたので、非常に簡単です。

static void Main()
{
    int i = 0;
    try
    {
        int j = 1 / i; // Generate a divide by 0 exception.
    }
    finally
    {

        Console.Out.WriteLine("Finished");
        Console.In.ReadLine();
    }
}

最初はここで説明した問題がありましたが、Visual Studio の外でプログラムを実行しようとすると、「プログラムが応答を停止しました」というエラーが発生しました。

4

5 に答える 5

13

トップレベルの例外ハンドラーがないため、.Net ランタイムが例外をキャッチし、最終的に実行する前にプログラムを中止します。これはポイントを示しています:

static void Main() 
{
  try
  {
      int i = 0;
      try
      {
         int j = 1 / i; // Generate a divide by 0 exception.
      }
      finally
      {
          Console.Out.WriteLine("Finished");
          Console.In.ReadLine();     
      }
  }
  catch (Exception ex)
  {
      Console.WriteLine(ex.ToString());
  }
}

このコードでは、呼び出しチェーンの上位の try...catch で例外が処理されるようになり (たまたま同じメソッド内にあるだけです)、埋め込みの finally が実行されます。キャッチは、例外が発生している同じ関数内にある必要はありません。呼び出しチェーン内のどこにでも配置できます。

編集: 最初は、いつ、どこで例外がプログラムによってキャッチされるかが不確かに思えるかもしれません。しかし、外の世界がコードと対話するアプリケーションの境界について考えてみてください。通常、それらは制限され、明確に定義されています。したがって、コンソール アプリケーションの場合、境界は Main メソッドであり、ここに最上位の例外ハンドラーを配置できます。Web フォーム アプリケーションの場合、境界にはボタン クリック イベント (ユーザーが UI を操作している) などが含まれるため、そこにも例外ハンドラーを含めることができます。クラス ライブラリの場合、境界は通常、ライブラリ自体ではなく、ライブラリを呼び出すアプリケーションの境界です。したがって、ライブラリで例外をキャッチしないでください (賢明に回復できる場合を除きます)。代わりに、呼び出し元のアプリケーションにバブルアップさせます。

于 2012-08-28T16:09:56.757 に答える
1

大規模なプログラムでは、DevideByZero例外が「バブルアップ」し、うまくいけば別の場所で処理されるため、これは問題になりません。これはmainメソッド内にあるため、例外には行き場がありません。これにより、表示される問題が発生します...

したがって、次は期待どおりに動作します

static void Main(string[] args)
{
    try
    {
        CatchTest();
    }
    catch (Exception)
    {

    }
}

private static void CatchTest()
{
    int i = 0;
    try
    {
        int j = 1 / i; // Generate a divide by 0 exception.    
    }
    finally
    {
        Console.Out.WriteLine("Finished");
        Console.In.ReadLine();
    }
}

これが役立つことを願っています。

于 2012-08-28T16:07:43.977 に答える
0

例外スローをキャプチャするには、キャッチが必要です。

int i = 0;
        try
        {
            int j = 1 / i; // Generate a divide by 0 exception.
        }
        catch(Exception e)
        {
            Console.Out.WriteLine("Exception caught");
        }
        finally
        {

            Console.Out.WriteLine("Finished");
            Console.In.ReadLine();
        }

この例外によりアプリケーションがクラッシュし、例外が処理されないため、アプリケーションが終了します。

http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.100).aspx

通常、未処理の例外がアプリケーションを終了する場合、finallyブロックが実行されるかどうかは重要ではありません。ただし、finallyブロックにそのような状況でも実行する必要のあるステートメントがある場合、1つの解決策は、try-finallyステートメントにcatchブロックを追加することです。

于 2012-08-28T16:01:27.763 に答える
0

デバッガーをデタッチする必要があります (たとえば、アプリケーションをリリース モードで実行する)。詳細については、次の (関連する) 質問を参照してください。

于 2012-08-28T16:10:21.333 に答える