由于某些原因,在我的控制台应用程序中,我无法运行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();
}
}
起初我有problem described here但后来我尝试在Visual Studio外部运行程序我得到了“程序已停止响应”错误。
答案 0 :(得分: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());
}
}
使用这段代码,异常现在处理了一个try ...在调用链中捕获更高的位置(它恰好在同一个方法中),因此最终将执行嵌入式。 catch不需要在引发异常的同一函数中,它可以在调用链中的任何位置。
编辑:最初看起来可能无法确定您的程序何时以及何处捕获异常。但请考虑应用程序的界限,外部世界与您的代码交互 - 通常它们是有限的并且定义良好。因此,对于控制台应用程序,边界是Main方法,这是您可以放置顶级异常处理程序的地方。对于Web表单应用程序,边界包括按钮单击事件(用户正在与UI交互)之类的内容,因此您也可以在其中使用异常处理程序。对于类库,边界通常是调用库的应用程序的边界,而不是库本身。所以不要在库中捕获异常(除非你可以明智地从它们中恢复),而是让它们冒泡到调用应用程序。
答案 1 :(得分:2)
想在这里添加我自己的发现,因为这里的行为肯定很奇怪-因此,公认的答案并不完全正确。
给出以下示例:
static void Main(string[] args)
{
try{
throw new Exception("");
} finally {
Console.WriteLine("I am never called!");
Console.ReadLine();
}
}
如果我们选择从Windows错误报告对话框中取消,则finally块实际上会执行,例如:
但是,如果我们允许Windows错误报告对话框“完成”,那么我们可以选择“调试”或“关闭程序”,则不会执行finally块。
对我来说,这表明.NET运行时实际上将运行所有finally块,而不管是否遇到“未处理的顶级异常”,并且阻止这样做的实际上是Windows(如果选择“关闭程序”)或Visual Studio调试器(如果您选择“调试”,或者正在连接调试器启动)...因为它们会在运行时之前杀死进程,从而有机会继续。
有什么想法吗?
答案 2 :(得分:1)
在一个较大的程序中,这不会是一个问题,因为DevideByZero
异常会“冒泡”并希望希望在其他地方处理。因为这是在main
方法中,所以例外无处可去。这会导致你看到的问题...
所以以下内容会按预期进行
static void Main(string[] args)
{
try
{
CatchTest();
}
catch (Exception)
{
}
}
private static void CatchTest()
{
int i = 0;
try
{
int j = 1 / i; // Generate a divide by 0 exception.
}
finally
{
Console.Out.WriteLine("Finished");
Console.In.ReadLine();
}
}
我希望这会有所帮助。
答案 3 :(得分:0)
你仍然需要一个捕获来捕获异常抛出:
int i = 0;
try
{
int j = 1 / i; // Generate a divide by 0 exception.
}
catch(Exception e)
{
Console.Out.WriteLine("Exception caught");
}
finally
{
Console.Out.WriteLine("Finished");
Console.In.ReadLine();
}
此异常导致应用程序崩溃,并且异常未处理,因此终止应用程序。
http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.100).aspx
通常,当未处理的异常结束应用程序时,无论finally块是否运行都不重要。但是,如果在finally块中有语句,即使在这种情况下也必须运行,一种解决方案是在try-finally语句中添加一个catch块。
答案 4 :(得分:0)
您需要分离调试器(例如,在发布模式下运行您的应用程序),请参阅以下(相关)问题以获取更多详细信息:finally doesn't seem to execute in C# console application while using F5