Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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.

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.

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.

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.

The current thread will not leave the current stack frame unless or until the "finally" block executes or an exception is thrown from within the finally block itself. If a thread dies or gets blocked within a "try" block, execution will never leave the current stack frame, but it won't execute the finally "block" either.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top