Why finally?

J

Jon Davis

I understand that the finally sub-block will execute regardless of whether
try succeeded or not. But so will code that follows try...catch. So then
what is the difference between ...

try {
do.something.that.breaks();
} catch {
do.something.that.works();
}
cleanup();


... and ..

try {
do.something.that.breaks();
} catch {
do.something.that.works();
} finally {
cleanup();
}

... other than organizational aesthetics ??

Thanks,
Jon
 
J

Jon Skeet [C# MVP]

Jon Davis said:
I understand that the finally sub-block will execute regardless of whether
try succeeded or not. But so will code that follows try...catch. So then
what is the difference between ...

try {
do.something.that.breaks();
} catch {
do.something.that.works();
}
cleanup();


.. and ..

try {
do.something.that.breaks();
} catch {
do.something.that.works();
} finally {
cleanup();
}

.. other than organizational aesthetics ??

1) You could return from the try block
2) You don't normally want to catch *all* exceptions - you catch a very
specific exception; the finally block still gets executed even if
the exception is propagated without being caught
3) More common is the try/finally form which doesn't have a catch block
at all - this is usually actually hidden by a "using" statement
which compiles to a try/finally.
 
S

Sericinus hunter

Jon said:
1) You could return from the try block
2) You don't normally want to catch *all* exceptions - you catch a very
specific exception; the finally block still gets executed even if
the exception is propagated without being caught
3) More common is the try/finally form which doesn't have a catch block
at all - this is usually actually hidden by a "using" statement
which compiles to a try/finally.

4) do.something.that.works(); may also throw an exception.
 
W

Willy Denoyette [MVP]

|I understand that the finally sub-block will execute regardless of whether
| try succeeded or not. But so will code that follows try...catch. So then
| what is the difference between ...
|
| try {
| do.something.that.breaks();
| } catch {
| do.something.that.works();
| }
| cleanup();
|
|
| .. and ..
|
| try {
| do.something.that.breaks();
| } catch {
| do.something.that.works();
| } finally {
| cleanup();
| }
|
| .. other than organizational aesthetics ??
|
| Thanks,
| Jon
|
|

In V2 of the framework, the finally block is guaranteed to run to
completion, even in the presence of an asynchronous exception (think
ThreadAbortExceptions).

Willy.
 
A

Alvin Bruney

That guarantee needs qualifications right? A finally block is not expected
to execute when the CLR throws a stack exception or an execution engine
exception. I take it that these form part of the qualification to the
*guarantee

--
________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Professional VSTO.NET - Wrox/Wiley 2006
 
J

Jon Davis

So you're saying that there is NO difference (in both examples the catch
blocks do not fail), but if the catch block does fail and is not handled
then the finally block will still execute.

Thanks,
Jon
 
B

Bruce Wood

Essentially, yes.

However, from a readability standpoint, "finally" is a nice guarantee
that "no matter what goes on in this code above, this bit will still
execute." When I see "finally" I don't have to do any reading of catch
blocks or checking to see what exceptions might be thrown: I know for
sure that the code in the "finally" block will execute _no matter
what_.

Anything that allows me to quickly pick up on what's going on in the
code is worth points, in my book.
 
M

Magnus

Jon Davis said:
I understand that the finally sub-block will execute regardless of whether
try succeeded or not. But so will code that follows try...catch. So then
what is the difference between ...

try {
do.something.that.breaks();
} catch {
do.something.that.works();
}
cleanup();


.. and ..

try {
do.something.that.breaks();
} catch {
do.something.that.works();
} finally {
cleanup();
}

.. other than organizational aesthetics ??

First of all, its not very common, or shouldn't be common to use catch all
statements.

The sole purpose of finally is to ensure that cleanup code is executed when
an exception is raised. Because of this it is also good code practise, c#
coders know that any cleanup will be within the finally block.

Using a finally block will also do a much better job than relying on catch
all statements and a subsequent line of code that in most cases will be
fired, but not all.
For example, consider the following cases:
- An exception is raised in the catch block, finally will be executed, your
first example will not.
- Some time in the future, the code is modified so that the catch statement
only catches specific exceptions, finally will be executed, your first
example will not.
- Some time in the future, your catch statement includes a return statement,
finally will be executed, your first example will not.
- Im sure there is more..

So no, its not just aesthetics, finally is for cleanup, your example just
happen to work in your idea of how the intended code will be executed, and
assumptions such as yours will cause you pain in the end.

- Magnus
 
W

Willy Denoyette [MVP]

By 'asynchronous' I mean that the exception is not initiated by an explicit
call to 'throw' in the executing code path (a thread).
Rather, it results from a memory allocation fault (OOM) or an injected
failure like Abort that can happen on any instruction in another thread (or
threads see: OOM). I don't consider StackOverFlow to be asynchronous, a
StackOverflow can't be injected in another thread. Note also that I'm not
talking about CER in V2 either, I'm just talking about a feature of the CLR,
that guarantees that the finally block will execute in the presence of an
asynchronous exception (Abort, OOM).

To see what I mean, consider this simple case, where an Abort is injected in
another thread:

class Tester
{
static void Main()
{
Thread t = new Thread(new ThreadStart(ThreadProc));
t.Start();
Thread.Sleep(150);
// Inject an asynchronous ThreadAbortException in the target thread,
// The choice of the sleep times guarantees that the exception occurs while
executing the finally backout code
t.Abort();
Console.WriteLine("Target Thread aborted");
}

static void ThreadProc()
{
IntPtr somePtr = IntPtr.Zero;;
try
{
somePtr = Marshal.AllocHGlobal(2000000);
Thread.Sleep(100);
}
finally
{
Thread.Sleep(200);
Marshal.FreeHGlobal(somePtr);
Console.WriteLine("Resource freed");
}
}
}
}

When running this on V2 of the framework, the CLR will prevent the
asynchronous abort (ThreadAbort or OOM) to be injected while running the
finally block. This means that the allocated resource will be freed despite
the presence of an asychronous exception.
However, when you run this code on V1.X, the finally will not run to an end
and the resource will leak.

Willy.



"Alvin Bruney" <www.lulu.com/owc> wrote in message
| That guarantee needs qualifications right? A finally block is not expected
| to execute when the CLR throws a stack exception or an execution engine
| exception. I take it that these form part of the qualification to the
| *guarantee
|
| --
| ________________________
| Warm regards,
| Alvin Bruney [MVP ASP.NET]
|
| [Shameless Author plug]
| The O.W.C. Black Book with .NET
| www.lulu.com/owc, Amazon
| Professional VSTO.NET - Wrox/Wiley 2006
| -------------------------------------------------------
|
| | >
| > | > |I understand that the finally sub-block will execute regardless of
| > whether
| > | try succeeded or not. But so will code that follows try...catch. So
| > then
| > | what is the difference between ...
| > |
| > | try {
| > | do.something.that.breaks();
| > | } catch {
| > | do.something.that.works();
| > | }
| > | cleanup();
| > |
| > |
| > | .. and ..
| > |
| > | try {
| > | do.something.that.breaks();
| > | } catch {
| > | do.something.that.works();
| > | } finally {
| > | cleanup();
| > | }
| > |
| > | .. other than organizational aesthetics ??
| > |
| > | Thanks,
| > | Jon
| > |
| > |
| >
| > In V2 of the framework, the finally block is guaranteed to run to
| > completion, even in the presence of an asynchronous exception (think
| > ThreadAbortExceptions).
| >
| > Willy.
| >
| >
|
|
 
J

Jon Davis

Bruce Wood said:
Essentially, yes.

However, from a readability standpoint, "finally" is a nice guarantee
that "no matter what goes on in this code above, this bit will still
execute." When I see "finally" I don't have to do any reading of catch
blocks or checking to see what exceptions might be thrown: I know for
sure that the code in the "finally" block will execute _no matter
what_.

Anything that allows me to quickly pick up on what's going on in the
code is worth points, in my book.

Which executes first, the raising of a new exception if the catch block
fails, or the finally block? (I presume the finally block would have to
execute first.)

Thanks,
Jon
 
S

Sericinus hunter

Jon said:
Which executes first, the raising of a new exception if the catch block
fails, or the finally block? (I presume the finally block would have to
execute first.)

Easy to check. And your assumption is correct if there is an outer
handler for this exception. However, if there is not, the framework
complains first.
 
A

Alvin Bruney

Yes, very nice. I get the same results from executing the code as well.
This seems to be a definite improvement of V1.x of the framework.

I did make a minor adjustment inside the try block of threadproc to throw an
exception. I did this to test to see if the finally block would hold for
normal exception paths (and to see if I could break the guarantee as well).
//inject an exception
for (int i = 0; i < 2; i++)
i = i % i;


After displaying the exception in a dialog box, it did fire the finally
block to release the resource.


--
________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Professional VSTO.NET - Wrox/Wiley 2006
-------------------------------------------------------

Willy Denoyette said:
By 'asynchronous' I mean that the exception is not initiated by an
explicit
call to 'throw' in the executing code path (a thread).
Rather, it results from a memory allocation fault (OOM) or an injected
failure like Abort that can happen on any instruction in another thread
(or
threads see: OOM). I don't consider StackOverFlow to be asynchronous, a
StackOverflow can't be injected in another thread. Note also that I'm not
talking about CER in V2 either, I'm just talking about a feature of the
CLR,
that guarantees that the finally block will execute in the presence of an
asynchronous exception (Abort, OOM).

To see what I mean, consider this simple case, where an Abort is injected
in
another thread:

class Tester
{
static void Main()
{
Thread t = new Thread(new ThreadStart(ThreadProc));
t.Start();
Thread.Sleep(150);
// Inject an asynchronous ThreadAbortException in the target thread,
// The choice of the sleep times guarantees that the exception occurs
while
executing the finally backout code
t.Abort();
Console.WriteLine("Target Thread aborted");
}

static void ThreadProc()
{
IntPtr somePtr = IntPtr.Zero;;
try
{
somePtr = Marshal.AllocHGlobal(2000000);
Thread.Sleep(100);
}
finally
{
Thread.Sleep(200);
Marshal.FreeHGlobal(somePtr);
Console.WriteLine("Resource freed");
}
}
}
}

When running this on V2 of the framework, the CLR will prevent the
asynchronous abort (ThreadAbort or OOM) to be injected while running the
finally block. This means that the allocated resource will be freed
despite
the presence of an asychronous exception.
However, when you run this code on V1.X, the finally will not run to an
end
and the resource will leak.

Willy.



"Alvin Bruney" <www.lulu.com/owc> wrote in message
| That guarantee needs qualifications right? A finally block is not
expected
| to execute when the CLR throws a stack exception or an execution engine
| exception. I take it that these form part of the qualification to the
| *guarantee
|
| --
| ________________________
| Warm regards,
| Alvin Bruney [MVP ASP.NET]
|
| [Shameless Author plug]
| The O.W.C. Black Book with .NET
| www.lulu.com/owc, Amazon
| Professional VSTO.NET - Wrox/Wiley 2006
| -------------------------------------------------------
|
| | >
| > | > |I understand that the finally sub-block will execute regardless of
| > whether
| > | try succeeded or not. But so will code that follows try...catch. So
| > then
| > | what is the difference between ...
| > |
| > | try {
| > | do.something.that.breaks();
| > | } catch {
| > | do.something.that.works();
| > | }
| > | cleanup();
| > |
| > |
| > | .. and ..
| > |
| > | try {
| > | do.something.that.breaks();
| > | } catch {
| > | do.something.that.works();
| > | } finally {
| > | cleanup();
| > | }
| > |
| > | .. other than organizational aesthetics ??
| > |
| > | Thanks,
| > | Jon
| > |
| > |
| >
| > In V2 of the framework, the finally block is guaranteed to run to
| > completion, even in the presence of an asynchronous exception (think
| > ThreadAbortExceptions).
| >
| > Willy.
| >
| >
|
|
 
W

Willy Denoyette [MVP]

"Alvin Bruney" <www.lulu.com/owc> wrote in message
| Yes, very nice. I get the same results from executing the code as well.
| This seems to be a definite improvement of V1.x of the framework.
|

Sure it is, hosted environments like ASP.NET and especially SQL Server,
where AD unloads do inject ThreadAbortExceptions into all running threads,
cannot afford resource leaks due to a finally block being aborted before
running to an end.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top