在C#中,如果关联的catch块抛出异常,是否可以强制控制通过finally块?

在C#中,如果关联的catch块抛出异常,是否可以强制控制通过finally块?,c#,java,exception,try-catch-finally,C#,Java,Exception,Try Catch Finally,我知道在Java中,如果一个异常被catch子句捕获,并且它的catch块抛出一个异常,那么在线程终止之前,控件将传递throw相关的finally块(如果有的话)。然而,C#中的情况似乎并非如此 在C#中几乎可以镜像这种行为,方法是将try finally语句放在try catch语句的try块中,其中包含引发异常的catch块,但如果:,finally块应该包含处理流编写器的代码,流编写器应该记录异常 有没有一种干净的方法可以在C#中实现类似java的try-catch-finally异常处

我知道在Java中,如果一个异常被catch子句捕获,并且它的catch块抛出一个异常,那么在线程终止之前,控件将传递throw相关的finally块(如果有的话)。然而,C#中的情况似乎并非如此

在C#中几乎可以镜像这种行为,方法是将try finally语句放在try catch语句的try块中,其中包含引发异常的catch块,但如果:,finally块应该包含处理流编写器的代码,流编写器应该记录异常

有没有一种干净的方法可以在C#中实现类似java的try-catch-finally异常处理行为

以下是请求的示例代码的更新:

StreamWriter writer = new StreamWriter("C:\\log.txt");
try
{
    throw new Exception();
}
catch (Exception e)
{
    writer.WriteLine(e.Message);
    throw e;
}
finally
{
    if (writer != null)
    {
       writer.Dispose();
    }
}
将该代码添加到控制台应用程序中,运行它,让重新抛出的异常不被处理,尝试删除C:\log.txt。您将不能,因为控件从未通过finally块。此外,如果在finally块中的某行中添加断点,您将看到它没有被命中。(我正在使用VS2005)

据我所知,强制控制通过finally块的唯一方法是,如果重新抛出的异常由封闭try块的catch块处理(如果您将上面的代码放在另一个try-catch语句的try块中)

如果未捕获异常并允许终止应用程序(如我提供的示例代码所示),则控件将不会通过finally块

在Java中,它会。在C#中,至少根据我所看到的,它不会

然而,C#中的情况似乎并非如此

这就是你要找的

然而,C#中的情况似乎并非如此

这就是你要找的

然而,C#中的情况似乎并非如此

这就是你要找的

然而,C#中的情况似乎并非如此


是您要找的。

不,这是不正确的。C#将始终执行
finally
块,即使从
catch
块抛出/重新抛出异常。请参阅。

不,这是不正确的。C#将始终执行
finally
块,即使从
catch
块抛出/重新抛出异常。请参阅。

不,这是不正确的。C#将始终执行
finally
块,即使从
catch
块抛出/重新抛出异常。请参阅。

不,这是不正确的。C#将始终执行
finally
块,即使从
catch
块抛出/重新抛出异常。请参阅。

如前所述,一旦执行catch块,finally块将始终运行

编辑:我刚刚在控制台应用程序中尝试了OP提供的示例代码,结果发现,它没有命中finally块,并且出现了一个错误“ConsoleApplication1.exe中发生了“System.exception”类型的未处理异常”。这确实令人费解(除了在无休止的循环中重新抛出相同的异常之外),所以我做了一些调查,我发现:

如果发生异常,CLR将遍历调用堆栈以查找 匹配的catch表达式。如果CLR找不到匹配的, 或者每次重新抛出异常时,异常都会冒泡出来 Main()方法的。在这种情况下,Windows将处理异常

控制台应用程序的事件处理最容易理解, 因为CLR没有特殊处理。例外是 如果未捕获,则保留应用程序线程。CLR将打开一个窗口 请求调试或退出应用程序。如果用户选择 调试时,调试器启动。如果用户选择关闭,则 应用程序退出,异常被序列化并写入 控制台


故事的寓意是,不要在控制台应用程序中从catch块重新抛出相同的异常

如前所述,一旦执行catch块,finally块将始终运行

编辑:我刚刚在控制台应用程序中尝试了OP提供的示例代码,结果发现,它没有命中finally块,并且出现了一个错误“ConsoleApplication1.exe中发生了“System.exception”类型的未处理异常”。这确实令人费解(除了在无休止的循环中重新抛出相同的异常之外),所以我做了一些调查,我发现:

如果发生异常,CLR将遍历调用堆栈以查找 匹配的catch表达式。如果CLR找不到匹配的, 或者每次重新抛出异常时,异常都会冒泡出来 Main()方法的。在这种情况下,Windows将处理异常

控制台应用程序的事件处理最容易理解, 因为CLR没有特殊处理。例外是 如果未捕获,则保留应用程序线程。CLR将打开一个窗口 请求调试或退出应用程序。如果用户选择 调试时,调试器启动。如果用户选择关闭,则 应用程序退出,异常被序列化并写入 控制台


故事的寓意是,不要在控制台应用程序中从catch块重新抛出相同的异常

如前所述,一旦执行catch块,finally块将始终运行

编辑:我刚刚在控制台应用程序中尝试了OP提供的示例代码,结果发现,它没有命中finally块,并且出现了一个错误“ConsoleApplication1.exe中发生了“System.exception”类型的未处理异常”。这确实令人费解(除了在无休止的循环中重新抛出相同的异常之外),所以我做了一些调查,我发现:

如果一个例外
try
{
  ...
}
catch
{
  throw;
}