C# 抛接逻辑
上述代码的输出为:C# 抛接逻辑,c#,.net,exception-handling,try-catch-finally,try-finally,C#,.net,Exception Handling,Try Catch Finally,Try Finally,上述代码的输出为:From Finally 为什么它不是Catch中的 -或- 如何从外部捕获和记录这两个异常?最终始终运行;而且它总是跑在最后。因此,内部尝试所做的最后一件事是最后一件,它抛出了被外部捕获的东西 不确定我是否理解问题的第2部分最后不管发生什么。无论try或catch中是否存在异常。因此,您可以看到“来自最终”。(这实际上是finally子句的全部目的。因此,您可以将代码放在其中,无论发生什么情况,都可以清理资源之类的东西,即使存在异常。)因为finally块在catch块之后执
From Finally
为什么它不是Catch中的
-或-
如何从外部捕获和记录这两个异常?最终始终运行;而且它总是跑在最后。因此,内部尝试所做的最后一件事是最后一件,它抛出了被外部捕获的东西
不确定我是否理解问题的第2部分最后
不管发生什么。无论try或catch中是否存在异常。因此,您可以看到“来自最终”。(这实际上是finally
子句的全部目的。因此,您可以将代码放在其中,无论发生什么情况,都可以清理资源之类的东西,即使存在异常。)因为finally块在catch块之后执行,覆盖异常
当在处理早期异常的过程中发生异常时,第一个异常将丢失
如何从外部捕获和记录这两个异常
通过不在最后一个区块内投掷。那总是个坏主意
如果要登录内部catch块,请使用throw
或将第一个异常作为新异常的InnerException传递。这就是InnerException
存在的原因
您的代码从try/catch/finally语句的每个部分抛出一个新的异常。在创建新错误时,您实际上是在吞咽以前的异常。您可以使用以下内容将“From Try”消息添加到“From Catch”消息中
try
{
try
{
throw new Exception("From Try");
}
catch
{
throw new Exception("From Catch");
}
finally
{
throw new Exception("From Finally");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
我不知道如何在finally中链接它。因为finally块总是被执行的
catch(Exception ex)
{
throw new Exception(ex.Message + ":" + "From Catch");
}
步骤(3)和(5)中的每个新异常对象都会丢弃上一个异常对象。由于始终执行finally块,因此所有剩余的是步骤(5)中的异常对象C。这是C语言规范定义的行为。在try
块中抛出的异常的处理被中止,而在finally
块中抛出的异常将被处理
相关的第8.9.5节throw语句解释了异常是如何传播的:
- 在当前函数成员中,将检查包含抛出点的每个
try
语句。对于每个语句S
,从最里面的try
语句开始,到最外面的try
语句结束,将计算以下步骤:
- 如果
S
的try块包含抛出点,并且S
具有一个或多个catch
子句,则将按外观顺序检查catch
子句,以找到适合异常的处理程序。指定异常类型或异常类型的基类型的第一个catch
子句被视为匹配。一般catch
子句(§8.10
)被视为与任何异常类型相匹配。如果找到了匹配的catch
子句,则通过将控制权转移到该catch
子句的块来完成异常传播
- 否则,如果
try
块或S
的catch
块包含抛出点,并且如果S
具有finally块,则控制权转移到finally块如果finally
块抛出另一个异常,则终止当前异常的处理。否则,当控制到达finally
块的终点时,继续处理当前异常
这是一个很好的问题,而且有点棘手。让我们一步一步地看一下:
try
{
try
{
throw new Exception("From Try");
// (1) A new exception object A is created here and thrown.
}
catch // (2) Exception object A is catched.
{
throw new Exception("From Catch");
// (3) A new exception object B is created here and thrown.
}
finally // (4) Execution is forced to continue here!
{
throw new Exception("From Finally");
// (5) A new exception object C is created here and thrown.
}
}
catch (Exception ex) // (6) Exception object C is catched.
{
Console.WriteLine(ex.Message);
}
在上面的代码中,catch子句抛出并捕获异常(“fromtry”)(到目前为止非常简单)。catch子句抛出它自己的异常,通常我们希望(因为catch嵌套在一个更大的try-catch块中)立即捕获该异常,但是
try
{
throw new Exception("From Try");
}
catch
{
throw new Exception("From Catch");
}
finally子句保证(尝试)执行,它位于第一位,并抛出它自己的异常,覆盖先前抛出的异常(“fromcatch”)
“catch和finally的常用用法
一起是为了获得和使用
try块中的资源,处理
捕获物中的特殊情况
块,然后释放中的资源
“最后一块”——
遵循这一系列逻辑,我们应该尽最大努力避免在catch和finally块中编写容易发生异常的代码。如果您担心出现类似您所介绍的情况,我建议将异常及其相关信息记录到外部文件中,您可以参考该文件进行调试。添加一层额外的try-catch块,如下所示:
finally
{
throw new Exception("From Finally");
}
报告:
try {
Exception fromCatch = null;
try {
throw new Exception("From Try");
}
catch {
try {
throw new Exception("From Catch");
}
catch (Exception e) {
// catch failed -> store exception
fromCatch = e;
}
}
finally {
try {
throw new Exception("From Finally");
}
catch (Exception e) {
// i can think of better exception merging... but this shows the idea
throw new Exception(e.Message, fromCatch);
}
// throw fromCatch, in case "From Finally did not happen"
throw fromCatch;
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
if (ex.InnerException != null) {
Console.WriteLine(ex.InnerException.Message);
}
}
编辑:这显然是第二个问题的答案,因为“为什么”已经得到了充分的回答:)棘手…期待着看到这个问题的答案。当然我不是在finally块中自己抛出异常,在finally块中释放资源时可以抛出异常,这是一种正常的行为,我想知道那里有一个异常,这与我想要“From Catch”异常没有冲突。@dxck,这不是那么正常。资源释放代码通常不应抛出。你有一个具体的例子吗?例如:写入临时文件失败是因为磁盘空间不足,然后在finally块中我想删除该文件,但失败是因为IO错误或有人弄乱了该文件(例如磁盘清理程序)。在临时文件成功打开后,您可以并且应该写入finally部分,以便它不会抛出。关闭不会抛出,在这些情况下也不会删除。如果临时文件写入网络共享,则网络不可用。写入和删除操作将失败。你不能保证这一点
From Finally
From Catch