为何这段官方C#代码中的finally代码块未执行?
问题:try-finally代码块中finally未执行(.NET 6)
现象
运行官方文档的示例代码时,finally代码块并未执行,仅输出未处理的异常信息:
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Int32'.
at ThrowTestA.Main() in C:\repos\Sandbox\Console\Console\Program.cs:line 14
测试代码
using System; public class ThrowTestA { public static void Main() { int i = 123; string s = "Some string"; object obj = s; try { // 无效转换:obj存储的是字符串,不是数值类型 i = (int)obj; // 以下语句不会被执行 Console.WriteLine("WriteLine at the end of the try block."); } finally { // 在Visual Studio中按CTRL+F5运行程序,然后在错误对话框中点击取消 Console.WriteLine("\nExecution of the finally block after an unhandled\n" + "error depends on how the exception unwind operation is triggered."); Console.WriteLine("i = {0}", i); } } // 官方文档预期输出: // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. // // Execution of the finally block after an unhandled // error depends on how the exception unwind operation is triggered. // i = 123 }
项目配置
<PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> </PropertyGroup> </Project>
原因与解决方案
在.NET 6及更高版本中,控制台应用的异常处理行为发生了变化:当未处理的异常触发时,运行时会直接终止进程,跳过finally块的执行。而官方文档的示例基于旧版本.NET Framework/早期.NET Core的行为,当时运行时会先执行finally再终止。
可通过以下方式让finally块执行:
显式捕获并重新抛出异常
在try外层添加catch块,捕获异常后重新抛出,确保finally先执行:using System; public class ThrowTestA { public static void Main() { int i = 123; string s = "Some string"; object obj = s; try { i = (int)obj; Console.WriteLine("WriteLine at the end of the try block."); } catch { throw; // 重新抛出异常,保证finally执行 } finally { Console.WriteLine("\nExecution of the finally block after an unhandled\n" + "error depends on how the exception unwind operation is triggered."); Console.WriteLine("i = {0}", i); } } }使用不调试的运行方式
在Visual Studio中按Ctrl+F5(不调试运行),当弹出错误对话框时点击取消,此时运行时会先执行finally块再终止进程。如果按F5调试运行,调试器会在异常抛出时立即中断,不会执行finally。
内容的提问来源于stack exchange,提问作者user33276346
相关产品推荐
相关产品推荐

