tags:

views:

130

answers:

6

Is there any even small possibility that finally will not be invoked but application still be running?

I'm releasing semaphore there

        finally
        {
            _semParallelUpdates.Release();
        }

and afraid of lost of some of them.

A: 

Host windows operating system will terminate the program even in worst cases of uncaught fatal exceptions. But yes even in that case finally block will surely get executed.

this. __curious_geek
Yep, in termination cases I don't need in semaphore because application crashed ;-) Well, then I should not worry about this "potential issue" then?
zerkms
This is not correct. In the case of a fatal exceptions such as an `ExecutingEngineException` there is no guarantee that a finally block will be executed. Also in case of out-of-band (asynchronous) exceptions such as `ThreadAbortException`, `StackOverflowException`, and `OutOfMemoryException` usually the executing thread is terminated resulting in the current AppDomain being unloaded so that a finally block may be interrupted or not reached at all. See [Reliability Best Practices](http://msdn.microsoft.com/en-us/library/ms228970.aspx) for further details.
0xA3
A: 

In Framework 1.0 and 1.1, this was possible if a thread which is currently in the finally block was aborted using Thread.Abort. In current versions of the framework, I'm not aware of any such cases.

Heinzi
A: 

yes:

try
{
   return result;
}
catch
{
   return result;
}
finally
{
  // does not get executed.
}

If you are asking about handling errors and such, the answer is No.

MrFox
What? The code as you've posted it is false.
Dan Tao
The whole purpose of the finally block, is that it is executed, specially in this case: http://msdn.microsoft.com/en-us/library/dszsf989(VS.71).aspx
GvS
+1  A: 

Only critical finalizers have a strong guaranty to be called in case the shit hits the fan. You can inherit from CriticalFinalizerObject or SafeHandle to get this behavior. However, letting your finalizer do anything else than call code with a strong reliability contract is not advised. This code has to be able to run for instance, in situations where the system is out of memory.

Implementing a critical finalizer is only needed in situations where you want to be sure all unhandled resources are cleaned even if the app domain is unloaded (because for instance). Please note that you of course never have any guarantee that finalizers will run. In case of a power failure, you're out of luck. If you need more guarantees, you need some sort of transactional system (such as a database) that can get you this behavior.

Steven
+1  A: 

If you are looking for ways to make your code reliable, I suggest reading the following article:

Reliability Best Practices

Another excellent article recommended by VinayC is the following:

Stephen Toub: Keep Your Code Running with the Reliability Features of the .NET Framework

0xA3
+1, here's another article that talks about CER: http://msdn.microsoft.com/en-us/magazine/cc163716.aspx
VinayC
@VinayC: Thanks. Indeed a great article. I added it to my answer to make the link more visible.
0xA3
A: 

Is it guaranteed that your code will reach the finally? Yes (barring some cataclysmic event such as the world coming to an end... or, you know, your computer losing power or your OS crashing).

But it's important to recognize that, if it's absolutely critical that your code runs, you better make sure your code doesn't throw an exception itself!

Take this for example:

IDisposable someDisposableObject = null;
IDisposable someOtherDisposableObject = null;

try
{
    someDisposableObject = GetDisposableObject();

    throw new Exception("Holy crap, something bad happened.");

    someOtherDisposableObject = GetOtherDisposableObject();
}
finally
{
    // This will throw a NullReferenceException...
    someOtherDisposableObject.Dispose();

    // ...so this actually won't run.
    someDisposableObject.Dispose();
}

So if you want your entire finally block to be run, it's important to write it properly so that an exception is (ideally) impossible.

Dan Tao
"it's important to write it properly so that an exception is (ideally) impossible": The problem here are asynchronous (out-of-band) exceptions which can be thrown in unexpected locations, possibly every machine instruction, like ThreadAbortException, StackOverflowException, and OutOfMemoryException. So basically even if you *reach* the finally block its execution might get interrupted even if your code does not throw a synchronous exception.
0xA3
@0xA3: Yeah, that's basically why I couldn't bring myself to say "impossible" without the qualifier "ideally": obviously you can't ever ensure that an exception is *impossible*. That said, you *can* do your best to ensure that an exception won't be thrown as a result of your own coding mistake *within* a `finally` block. That's all I was getting at.
Dan Tao