Is it possible to determine if code is currently executing in the context of a finally
handler as a result of an exception being thrown? I'm rather fond of using the IDisposable
pattern to implement entry/exit scoping functionality, but one concern with this pattern is that you might not necessarily want the end-of-scope behavior to occur if an exception occurs in the body of the using
. I'd be looking for something like this:
public static class MyClass
{
public static void MyMethod()
{
using (var scope = MyScopedBehavior.Begin())
{
//Do stuff with scope here
}
}
}
public sealed class MyScopedBehavior : IDisposable
{
private MyScopedBehavior()
{
//Start of scope behavior
}
public void Dispose()
{
//I only want to execute the following if we're not unwinding
//through finally due to an exception:
//...End of scope behavior
}
public static MyScopedBehavior Begin()
{
return new MyScopedBehavior();
}
}
There are other ways I can accomplish this (pass a delegate to a function that surrounds the call with particular behavior), but I'm curious if it's possible to do it using the IDisposable
pattern.
Actually, this has apparently been asked and answered before here. It's possible to detect in a very hackish sort of way. I wouldn't actually use that technique, but it's interesting to know that it's possible.
A finally block always executes, regardless of whether an exception is thrown.
The "finally" block execution stops at the point where the exception is thrown. Irrespective of whether there is an exception or not "finally" block is guaranteed to execute. Then the original exception that occurred in the try block is lost.
A finally block is always get executed whether the exception has occurred or not. If an exception occurs like closing a file or DB connection, then the finally block is used to clean up the code.
The finally block executes regardless of whether an exception is thrown or caught.
The means of accomplishing this that I've seen require an extra method:
public static void MyMethod()
{
using (var scope = MyScopedBehavior.Begin())
{
//Do stuff with scope here
scope.Complete(); // Tells the scope that it's good
}
}
By doing this, your scope object can track whether it's disposing because of an error, or a successful operation. This is the approach taken by TransactionScope, for example (see TransactionScope.Complete).
As a side point, IL allows you to specify SEH fault
blocks that are similar to finally
but are entered only when an exception is thrown - you can see an example here, about 2/3rds down the page. Unfortunately, C# doesn't expose this functionality.
I was looking for something similar for unit testing - I have a helper class I use to clean up objects after a test run and I want to keep the nice, clean 'using' syntax. I also wanted the option of not cleanup up if the test failed. What I came up with is to call Marshal.GetExceptionCode(). I don't know if this is appropriate for all cases, but for test code it seems to work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With