我怎样才能传递例外?

时间:2012-12-17 21:04:26

标签: c# exception

基本上,我想要做的是在同一个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 else条款下复制TimeoutException的代码。我希望处理所有异常的原因是可能存在其他未知异常。程序的性质要求它不会崩溃,所以我必须考虑任何其他异常并记录它们。我该如何实现呢?

2 个答案:

答案 0 :(得分: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”只会捕获TimeoutException,因此任何其他异常将始终转到外部作用域。当你重新抛出时,它也会自动被外部范围捕获,这消除了杀死异常信息的需要。 (如果您throw new Exception,您将丢失堆栈跟踪数据以及其他非常有价值的调试信息。)

答案 1 :(得分: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;
    }
}