Ensure that the try … finally … and will be executed using
October 27, 2011
Speaking in c # and using try … finally … I think most people are not unfamiliar, these two structures in C # plays vital important role, is to throw an exception when the procedure will still be able to ensure the execution of a part of the code, for the try … finally … is in the try block throws an exception, to ensure that the finally block still execute the code, for using that code in a using block, an exception is thrown when the implementation is still an object in a using statement on the interface IDisposable.Dispose method (mentioned later in this fact or through the try … finally … to achieve).
but you are sure you try … finally … block will execute when an exception occurs finally, your exception occurs when using block the Dispose method will execute it?
We first look at try … finally …, Please create a console project, paste the following code: using System;
using System.Collections . Generic;
using System.Linq;
using System.Text;
namespace ExceptionTest
{
class Demo: IDisposable
{
public void Dispose ()
{
Console . WriteLine (“Execute Dispose!”);
}
}
class Program
{
static void TryFinallyTest ()
{
Demo demo = new Demo ();
try
{
throw new Exception ();
}
finally
{
demo.Dispose ();
}
}
static void Main (string [] args)
{
TryFinallyTest ();
}
}
}
this sections of the code was simply an exception occurs in the try block is executed after demo.Dispose () outputs a string on the console, but run the code, whether in the point of throwing an exception (ie, not debugging), you will find the results of control What stage are not output, and the procedures of the process is terminated.
This shows where the try … finally … block after an exception occurs not in the finally block demo.Dispose (), and earlier this is not said contrary to it?
close the console, we are once again the above code, an exception is thrown when the choice is, and VS entering the debug state, choose Stop Debugging.
The results we found that an exception is thrown on the console, and display Execute Dispose!, it is clear that the finally block demo.Dispose () executed after the exception is thrown.
Please note that you can in the windows task manager to view the process in both cases the existence of the state program is different, if you throw an exception and click No, then you will find the program the end of the process immediately, but you throw an exception and click, you will find the application process does not end immediately, but wait until the output Execute Dispose! after the process until the end. This phenomenon is very clear that the first case the finally block will not reason is that the program after an exception is thrown in the try, the finally block is not enough time, the program process immediately terminated by the operating system. The same situation also appears in the windows project, please refer to the last sample code.
visible in the windows console project and the project after the try block throws an exception if not in the corresponding catch block to catch the exception, the program will result in immediate termination of the process, eventually leading to the execution of the finally block would have the code is not implemented. Well, in order to try … finally … the finally always be executed, then we find a way to try the program after an exception is thrown in the process not to be terminated immediately, but wait until the finally block is executed and then terminated , there is a very simple way to achieve this requirement, see the following code: using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ExceptionTest
{
class Demo: IDisposable
{
public void Dispose ()
{
Console.WriteLine (“Execute Dispose!”);
}
}
class Program
{
static void InnerTryFinallyTest ()
{
try
{
Demo demo = new Demo ();
try
{
throw new Exception ();
}
finally
{
demo.Dispose ();
}
}
catch
{
throw;
}
}
static void Main (string [] args)
{
InnerTryFinallyTest ();
}
}
}
in the method InnerTryFinallyTest in We will try … finally … structure on another try … catch … structure, such a nested structure plays a key role, is to try … finally … structure after an exception occurs in the try block, the exception does not immediately reported to the operating system, but before the exception is passed to the outer try … catch … the structure of the try block, the outer try block first ensure the implementation of its internal code have been executed after the exception is passed to catch block (which called for the execution of the code refers to the internal structure of the try … finally … finally block code), the last catch block using the key word and then throw the caught exception thrown to the operating system intact, then the program is the operating system terminates the process immediately. Execute the above code to be:
Sure enough, this exception is thrown to the operating system before the implementation of the finally block.
Then we look at using the structure, c # in using the structure presented here is not to be, do not know of a friend, please consult the MSDN relevant parts. You will be found on MSDN the final structure will actually be using the compiler convert the structure to try … finally … If using the following structure:
using (Demo demo = new Demo ( ))
{
throw new Exception ();
}
compiler actually obtained is structured as follows:
Demo demo = new Demo ();
try
{
throw new Exception ( );
}
finally
{
if (demo! = null)
((IDisposable) demo). Dispose ();
}
so the windows console project and projects, in try … finally … structural problems, it will also appear in using the structure, see the following code: using System;
using System.Collections.Generic;
using System.Linq; < br />
using System.Text;
namespace ExceptionTest
{
class Demo: IDisposable
{
public void Dispose ()
{
Console.WriteLine (“Execute Dispose!”);
}
}
class Program
{
static void UsingTest ()
{
using (Demo demo = new Demo ())
{
throw new Exception ();
}
}
static void Main (string [] args)
{
UsingTest (); < br />
}
}
}
not on the same console output Execute Dispose!, proved using structural throw exceptions, does not perform IDisposable.Dispose () method, because that is using the program after an exception occurs within the structure of the process was immediately terminated. Similarly, using the structure in the outer structure with try … catch … the structure can be avoided using an exception process is terminated immediately after the program: using System;
using System.Collections.Generic ;
using System.Linq;
using System.Text;
namespace ExceptionTest
{
class Demo: IDisposable
{
public void Dispose ()
{
Console.WriteLine (“Execute Dispose!”);
}
}
class Program
{
< br /> static void InnerUsingTest ()
{
try
{
using (Demo demo = new Demo ())
{
throw new Exception ();
}
}
catch
{
throw;
}
}
static void Main (string [] args)
{
InnerUsingTest ();
}
}
}
This will be executed before the program terminates the process IDisposable.Dispose () method output Execute Dispose! up.
console project and above all windows for the discussion of the project started, in fact, lead to the ultimate cause of the problem or because the two projects will throw an exception to the operating system, the project process will terminated by the operating system. So for the ASP.NET project will not have this problem? We all know the code for ASP.NET by IIS process to be responsible for implementation, and code of ASP.NET exception occurs, the exception information will be output on the page, IIS terminates the process and will not be lost, so is than that in ASP.NET try … finally … there is no structure and structure of these problems using it? We create a new ASP.NET web application and create a library file, enter the following code: using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace WebAppException
{
< br /> class Demo: IDisposable
{
public void Dispose ()
{
string path = HttpContext . Current.Server.MapPath (“~/”) “Log.txt”;
StreamWriter sw = new StreamWriter (path, true);
sw.WriteLine ( “Execute Dispose!”);
sw.Close ();
}
}
class EClass < br />
{
public static void TryFinallyTest ()
{
Demo demo = new Demo ();
try
{
throw new Exception ();
}
finally
{
demo.Dispose ();
}
}
public static void UsingTest ()
{
using (Demo demo = new Demo ())
{
throw new Exception ( );
}
}
}
}
Log implementation found . txt in a line of Execute Dispose! text, which shows that try … finally … the structure in the try block throws an exception because the IIS process is not terminated after the execution of the finally block has the same execution EClass.UsingTest () will be the same result. Does not exist in ASP.NET can be seen the problem described in this article.
shows that try … finally … the structure and using the structure in the performance of different projects in different behavior, specifically, the project itself in the process of throwing an exception will terminated by the operating system, here I only tested the windows project, console project and ASP.NET, on. NET, and other items if you encounter the same problem can learn from the content described in this article (the outer layer of nested try .. . catch … structure) to deal with.
Finally, the article sample code (code written using VS2010):
