web-dev-qa-db-ja.com

例外がスローされてキャッチされた後にコードの実行を再開する

例外がスローされた後、どのようにコード実行を再開できますか?

たとえば、次のコードを使用します。

namespace ConsoleApplication1
{
    public class Test
    {
        public void s()
        {
            throw new NotSupportedException();
            string @class = "" ;
            Console.WriteLine(@class);
            Console.ReadLine();
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                new Test().s();
            }
            catch (ArgumentException x)
            {
            }
            catch (Exception ex)
            {
            }
        }
    }
}

ステップスルー時に例外をキャッチすると、プログラムの実行が停止します。どうすれば実行を続けることができますか?

編集:私が具体的に意味するのは、Console.WriteLine(@class);という行です。デバッグモードのときに実行すると、プログラムはデバッグモードを終了するため、ヒットしないようです。私はこの行まで走り、そこで止まりたいです。

ありがとう

28
GurdeepS

再開可能な例外が必要なようです。 C#は再開可能な例外を実行しません。CLRがそれらをサポートしていることは疑わしいです。

例外をスローする目的は、呼び出し環境(パラメーター、オブジェクト状態、グローバル状態)の何かが関数の操作を不可能または無効にする場合に、関数と操作全体(呼び出しスタック)を中止することです。たとえば、ゼロのパラメーターを、そのパラメーターで数量を除算する必要がある関数に渡します。ゼロによる除算は意味のある結果を生成しません。それが関数の唯一の目的である場合、関数は意味のある結果を返すこともできません。したがって、例外をスローします。これにより、実行は呼び出しスタックの最も近いキャッチにジャンプするか、最終的にブロックされます。例外をスローした関数に戻ることはありません。

デバッガでコードにステップインしてConsole.WriteLine()呼び出しをトレースする場合は、コードからthrow New NotSupportedException()行を削除して再コンパイルする必要があります。

10
dthorpe

メソッドで例外がスローされることを心配しているが、メソッドを続行したい場合は、メソッド内にエラーハンドラーを追加します。

class Test 
{ 
    public void s() 
    { 
        try
          {
              // Code that may throw an exception
              throw new NotSupportedException();
          } 
          catch(Exception ex)
          {
              // Handle the exception - log?, reset some values?
          }
          string @class = "" ; 
          Console.WriteLine(@class); 
          Console.ReadLine(); 
    } 
} 

状態を示すブール値またはその他の値を返すこともできます。

8
Patrick

免責事項:実際にこれを行うことはお勧めしません。

次のコードを使用すると、古いVBスタイルOn Error Resume Nextを模倣することができます。

public static class ControlFlow
{
  public static Exception ResumeOnError(Action action)
  {
    try
    {
      action();
      return null;
    }
    catch (Exception caught)
    { 
      return caught;
    }
  }
}

そして、次のように使用できます。

public static void Main()
{
  ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); });
  ControlFlow.ResumeOnError(() => { Console.WriteLine(); });
  ControlFlow.ResumeOnError(() => { Console.ReadLine(); });
}
3
Brian Gideon

Catchブロック内にスローされる例外をキャッチするためにまとめた簡単なコード:

try
{
    //do code here
}
catch (Exception ex)
{
    try { SomeMethod1(); }
    catch { }

    try { SomeMethod2(); }
    catch { }

    try { SomeMethod3(); }
    catch { }
}
finally
{
    //cleanup goes here
}
1

実行は引き続き実行されますが、例外がキャッチされた後はコードはありません。 sを繰り返し呼び出す場合は、whileループでtry/catchブロックをラップすることを検討してください。

0
JB King

Main()メソッドで実行される次のコードがないため、プログラムは実行を停止します!コードに次の行を追加して、コンソール入力があるまでプログラムを実行し続けることができます。

Console.ReadLine();
0
Marius Schulz

そのコードでは、できません。タスクを小さなチャンクに分割すると、次のチャンクから再開できます。ただし、通常は、続行するかどうかを返すコールバック関数など、致命的でないエラーを報告する例外とは異なるメカニズムを使用する方が簡単です。

0
Pete Kirkham

デバッグで「ステップオーバー」機能を使用して、実行ごとにこれを実現できます。

0
Matt Mitchell