3

基本的に、私がやりたいことは、同じ try ブロック内で特定の Exception をより一般的な Exception に渡すことです。私は次のことを試しましたが、うまくいきません:

    static bool example(int count = 0)
    {
        try
        {
            work();
        }
        catch (TimeoutException e)
        {
            if (count < 3)
            {
                Console.WriteLine("Caught TimeoutException: {0}", e.Message);
                return example(count + 1);
            }
            else
            {
                throw new Exception(e.Message);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Caught Exception: {0}", e.Message + " rethrown");
            return false;
        }
        return true;
    }

    static void work()
    {
        throw new TimeoutException("test");
    }

よりTimeoutException一般的なException. これはTimeoutException、ケースバイケースで例外に関する追加情報があるためです。の句のException下ののコードを複製したくありません。すべての例外を処理したい理由は、他にも未知の例外がスローされる可能性があるためです。プログラムの性質上、クラッシュしないようにする必要があるため、他の例外を考慮してログに記録する必要があります。どうすればこれを実装できますか?elseTimeoutException

4

2 に答える 2

6

これをこの方法で処理したい場合は、これを 2 回ネストする必要があります。

static bool example(int count = 0)
{
  try
  {
    try
    {
        work();
    }
    catch (TimeoutException e)
    {
        if (count < 3)
        {
            Console.WriteLine("Caught TimeoutException: {0}", e.Message);
            return example(count + 1);
        }
        else
        {
            // Just throw, don't  make a new exception
            throw; //  new Exception(e.Message);
        }
    }
  }
  catch (Exception e)
  {
        Console.WriteLine("Caught Exception: {0}", e.Message + " rethrown");
        return false;
  }
  return true;
}

「内側の try/catch」は catch のみTimeoutExceptionであるため、他の例外は常に外側のスコープに移動します。再スローすると、自動的に外側のスコープにもキャッチされるため、例外情報を強制終了する必要がなくなります。(throw new Exceptionそうすると、スタック トレース データやその他の非常に貴重なデバッグ情報が失われます。)

于 2012-12-17T21:07:32.690 に答える
2

これが私の見解です:

bool example()
{
    // Attempt the operation a maximum of three times.
    for (int i = 0; i < 3; i++)
    {
        try
        {
            work();
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine("Caught exception {0}", e.Message);

            // Fail immediately if this isn't a TimeoutException.
            if (!(e is TimeoutException))
                return false;
        }
    }

    return false;
}

編集

実際に TimeoutException で何かをしたい場合は、catch ブロックを次のように変更できます。

catch (Exception e)
{
    // As Reed pointed out, you can move this into the if block if you want
    // different messages for the two cases.
    Console.WriteLine("Caught exception {0}", e.Message);

    TimeoutException timeoutException = e as TimeoutException;
    if (timeoutException != null)
    {
        // Do stuff with timeout info...
    }
    else
    {
        // Not a timeout error, fail immediately
        return false;
    }
}
于 2012-12-17T21:19:54.820 に答える