Fr3*_*dan 3 c# exception-handling try-finally
出于某种原因,在我的控制台应用程序中,我无法运行我的finally块.我正在编写此代码来测试finally块的工作方式,因此非常简单:
static void Main()
{
int i = 0;
try
{
int j = 1 / i; // Generate a divide by 0 exception.
}
finally
{
Console.Out.WriteLine("Finished");
Console.In.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
Pol*_*fun 11
因为您没有顶级异常处理程序,所以.Net运行时正在为您捕获异常并在最终有机会运行之前中止该程序.这说明了这一点:
static void Main()
{
try
{
int i = 0;
try
{
int j = 1 / i; // Generate a divide by 0 exception.
}
finally
{
Console.Out.WriteLine("Finished");
Console.In.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
使用这段代码,异常现在处理了一个try ...在调用链中捕获更高的位置(它恰好在同一个方法中),因此最终将执行嵌入式.catch不需要在引发异常的同一函数中,它可以在调用链中的任何位置.
编辑:最初可能看起来不确定您的程序将捕获异常的时间和地点.但要考虑应用程序的界限,外部世界与您的代码交互 - 通常它们是有限的并且定义良好.因此,对于控制台应用程序,边界是Main方法,这是您可以放置顶级异常处理程序的地方.对于Web表单应用程序,边界包括按钮单击事件(用户正在与UI交互)之类的内容,因此您也可以在其中使用异常处理程序.对于类库,边界通常是调用库的应用程序的边界,而不是库本身.所以不要在库中捕获异常(除非你可以明智地从它们中恢复),但是让它们冒泡到调用应用程序.
想在这里添加我自己的发现,因为这里的行为肯定很奇怪 - 因此,接受的答案并不完全正确。
给出以下示例:
static void Main(string[] args)
{
try{
throw new Exception("");
} finally {
Console.WriteLine("I am never called!");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们选择从 Windows 错误报告对话框中取消,finally 块实际上会被执行,如下所示:
但是,如果我们允许 Windows 错误报告对话框“完成”,因此我们可以选择“调试”或“关闭程序”,则不会执行 finally 块。
对我来说,这表明.NET运行时实际上会运行所有finally块,无论遇到“未处理的顶级异常”,并且阻止它这样做的实际上是Windows(如果您选择“关闭程序”)或Visual Studio 调试器(如果您选择“调试”或在附加调试器的情况下启动)...因为它们会在运行时之前终止进程作为继续的机会。
有什么想法吗?
| 归档时间: |
|
| 查看次数: |
1965 次 |
| 最近记录: |