Problem:
I had used .NET Mass Downloader tool to download .NET 2.0 Framework sourcecode some time ago. While reading Timer.cs (System.Windows.Forms.Timer) and a couple of other classes I noticed something interesting.
Does the following piece of code look odd to you? Notice the empty “try” block and all processing being done in the “finally” block.
public void Foo()
{
try
{
}
finally
{
DoSomething();
DoSomethingElse();
}
}
It’s (most likely, you’d think – right?) not the work of a programmer misunderstanding what was asked of him
Solution:
This methodology guards against a Thread.Abort call interrupting the processing. The MSDN page of Thread.Abort says that “Unexecuted finally blocks are executed before the thread is aborted”. So in order to guarantee that your processing finishes even if your thread is aborted in the middle by someone calling Abort on your thread, you can place all your code in the finally block (the alternative is to write code in the “catch” block to determine where you were before “try” was interrupted by Abort and proceed from there if you want to).
But what if your thread is aborted while code in the finally block is executing?
Again, here’s what the MSDN page says:
“In the .NET Framework versions 1.0 and 1.1, there is a chance the thread could abort while a finally block is running, in which case the finally block is aborted.“
That’s bad because this behavior could potentially cause leakage of resources if you have your code for freeing up resources written in the “finally” block and it got interrupted in the middle by a call to Abort.
What about .NET 2.0:
I wrote a simple program to check the behavior and on my machine running .NET 2.0 on Vista Enterprise edition, finally block isn’t interrupted even if an Abort call is made on the thread running the “finally” block.
The Code:
I had a function named LaunchThread to start the thread. This function was called from the handler for the “Load” event of the form.
private Thread mThread;
public void LaunchThread()
{
this.mThread = new Thread(ThreadMain);
this.mThread.Start();
}
I had a button on my form. I had a handler for its Click event which basically called Abort on the thread.
private void button1_Click(object sender, EventArgs e)
{
if (this.mThread != null && this.mThread.IsAlive)
{
this.mThread.Abort();
this.mThread.Join();
MessageBox.Show(“Thread Aborted”);
}
else
{
MessageBox.Show(“Thread already died”);
}
}
This is what ThreadMain looked like:
public void ThreadMain()
{
try
{
}
finally
{
MessageBox.Show(“Going to sleep!”);
Thread.Sleep(10000);
MessageBox.Show(“Just finished sleeping!”);
}
}
To test the application, I ran the application, waited a couple of seconds and then clicked on the button. Here is the sequence of messages that appeared:
- As soon as the form was launched – “Going to sleep!
- No messages appeared in response to me clicking on the button.
- After 10 seconds – “Just finished sleeping!”
- And immediately after that – “Thread Aborted”
Since no message appeared in response to me clicking on the button, it is clear that Thread.Sleep call in the “finally” block was not interrupted by Abort.
Changing ThreadMain like the following, leads to different results:
public void ThreadMain()
{
try
{
MessageBox.Show(“Going to sleep!”);
Thread.Sleep(10000);
MessageBox.Show(“Just finished sleeping!”);
}
finally
{
}
}
In this case, when I clicked on the button, Thread.Sleep call was interrupted by the call to Abort as I saw the following messages:
- As soon as the form was launched – “Going to sleep!”
- Just after clicking on the button “Thread aborted”





Great post but even greater observation
[...] The Empty Try Block Mystery (Siddharth Uppal) [...]
Excellent, I’m going to have to write this down somewhere!
[...] The empty try block mystery I had used .NET Mass Downloader tool to download .NET 2.0 Framework sourcecode some time ago. While reading Timer.cs (System.Windows.Forms.Timer) and a couple of other classes I noticed something interesting. [...]
Cool!
The finally{} block is a critical section. There are other ways of creating critical sections, such as using lock(). I know lock won’t keep a thread from aborting, but I believe there is another way to mark a section as critical that will keep the thread abort monster away. But I don’t have my CLR Via C# handy and can’t remember it.
This is also an example why you need to be VERY careful of what you do in a finally block. If you get into a race condition within one, good luck recovering.
Thanks everyone for comments. It’s encouraging
@Will,
“finally” isn’t a critical section by itself. In general, you can have two threads executing the finally block of the same method at the same time. However, “lock” uses “try” and “finally” under the hood.
The following piece of code:
lock(orange)
{
DoSomething();
}
… is munged by the compiler to IL achieving the following:
Monitor.Enter(orange);
try
{
DoSomething();
}
finally
{
Monitor.Exit(orange);
}
So you are right in that, the “finally” generated by the compiler when it sees “lock” is a critical section because of the Monitor.Enter call that preceded it. But I’m not sure if you were thinking that deep
“finally” isn’t a critical section on its own.
As for other alternatives to “lock”, one could use any of Monitor, Mutex or Semaphore to implement critical sections. Not sure if you were referring to them.
Thanks for this enlightening post.
[...] The empty try block mystery – Siddharth Uppal highlights an interesting tip discovered by reading the .NET Framework code. [...]
[...] The empty try block mystery [...]
Great post
[...] The empty try block mystery [...]
[...] why you would have a try/finally with an empty “try” in the first place, you might find an earlier article of mine [...]
Thanks Siddharth, helped a lot.
The lock statement is implemented as a try/finally block pair where the Monitor.Exit() call is suposed to be executed within the finally block, thus ensuring the release, but what about 1.1?
If a Thread.Abort in 1.1 is capable of interrupting a finally block during its execution it means that you can produce a deadlock if you abort a thread that locked some given resource and is about to release it.
The good resource is informative and actual
Great post! I bet you put a lot of research into it.