在C#中,如果关联的catch块引发异常,是否可以强制控制通过finally块? [英] in C# is it possible to force control to pass through a finally block if an exception is thrown by an associated catch block?

查看:90
本文介绍了在C#中,如果关联的catch块引发异常,是否可以强制控制通过finally块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在Java中,如果catch子句捕获了异常,并且其catch块引发了异常,则控制将在线程终止之前传递与关联的finally块(如果有).但是,在C#中似乎并非如此.

I know that in Java, if an exception is caught by a catch clause and its catch block throws an exception, control would pass throw the associated finally block (if any) before the thread is terminated. This does not appear to be the case in C#, however.

通过在try-catch语句的try块中放置一个try-finally语句与引发异常的catch块,可以在C#中几乎反映出这种行为,但这是一个问题,例如,则finally块应该包含处理应记录异常的Stream Writer的代码.

It is possible to almost mirror this behavior in C# is by putting a try-finally statement inside the try block of the try-catch statement with the catch block that throws the exception, but that would be a problem if, for example, the finally block is supposed to contain code that disposes a Stream Writer that is supposed to log the exception.

是否有一种干净的方法在C#中实现类似Java的try-catch-finally异常处理行为?

Is there a clean way to achieve java-like try-catch-finally exception handling behavior in C#?

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

Here's an update with the requested sample code:

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).

Add that code to a console application, run it, let the re-thrown exception go unhandled, attempt to delete C:\log.txt. You won't be able to, because control never passed through the finally block. Also, if you add a breakpoint to some line inside the finally block you will see that it doesn't get hit. (I'm using VS2005).

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

As far as I know, the only way to force control to pass through the finally block is if the re-thrown exception is handled by the catch block of an enclosing try block (if you took the code above and placed it inside the try block of another try-catch statement).

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

If the exception is not caught and is allowed to terminate the application, as in the sample code I provided, control won't pass through the finally block.

在Java中会.至少根据我所见,在C#中不会.

In Java it would. In C#, at least based on what I have seen, it would not.

推荐答案

在.NET Framework中,当发生异常时,系统将确定在执行任何finally块之前是否有任何东西要捕获该异常.根据各种应用程序设置,尝试抛出将不会被捕获的异常可能会立即杀死该应用程序,而不会给任何finally块(或其他任何块)运行的机会.

In the .NET Framework, when an exception occurs, the system will determine what if anything is going to catch that exception before any finally blocks execute. Depending upon various application settings, an attempt to throw an exception which will not be caught may kill the application instantly, without giving any finally blocks (or anything else) a chance to run.

如果将Main方法以及每个线程都包装在

If one wraps the Main method, as well as each thread, in

try
{
  ...
}
catch
{
  throw;
}

,那么在try块中引发的任何异常都将被捕获.即使将立即重新抛出,任何嵌套的finally块也将在catch之前执行.在某些情况下,这是理想的行为.在其他情况下,可能希望例如如果不会捕获到异常,则执行一些特殊的日志记录(在某些情况下,如果finally块有机会先运行,则一个人希望记录的信息可能会被破坏).在C#中,没有任何方法可以根据是否要捕获异常来改变一个人的行为,但是在VB.NET中,可以通过一些方法来完成.调用C#代码的VB.NET程序集可以使该代码知道是否由内部方法引发的任何异常将传播到vb.net包装器而不会被捕获.

then any exception which is thrown within the try block will get caught. Even though it will be immediately re-thrown, any nested finally blocks will execute before the catch. There are some cases where this is desirable behavior; there are other cases where one may wish to e.g. perform some special logging if an exception isn't going to be caught (in some cases, the information one wishes to log may be destroyed if the finally blocks get a chance to run first). Within C#, there isn't any way to vary one's actions based upon whether an exception is going to be caught, but in VB.NET there are some ways via which that can be done; a VB.NET assembly which makes calls to C# code can give that code a way of knowing whether any exceptions thrown by an inner method will propagate out to the vb.net wrapper without being caught.

这篇关于在C#中,如果关联的catch块引发异常,是否可以强制控制通过finally块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆