Matias Cicero
Matias Cicero

Reputation: 26321

C# - Infinite Loop at Exception Throwing?

I have the following code:

protected void ExecuteInTransaction(Action action)
{
    using (SQLiteTransaction transaction = connection.BeginTransaction())
    {
        try
        {
            action.Invoke();
            transaction.Commit();
        }
        catch(Exception)
        {
            transaction.Rollback();
            throw;
        }
    }
}

While testing this class, I managed to throw an exception in order to test the catch branch.

Exception Thrown

As I'm in Debug mode, I continue the execution of this throwing, to see how the calling class handles it, but the exception is never thrown by the method, instead, it's like the exception is constantly being thrown and caught, thrown and caught all over again, never exiting the function.

In Release mode, the application freezes and stops working:

Frozen Application

Does anybody know why this is happening, and how can I avoid it?

Thanks in advance!

Upvotes: 2

Views: 6090

Answers (4)

CL.
CL.

Reputation: 180210

There is no infinite loop. Visual Studio just stops at the place where the uncaught exception would abort the program. Trying to continue does nothing because there is nothing further to execute (VS just displays the same message again to remind you of that).

If you had a try/catch handler in some calling function, you would be able to debug into there. (But if that catch handler rethrows again, VS would stop there, too.)


Please note that SQLiteTransaction automatically handles rolling back when an open transaction is disposed; it is designed so that your code can be simpler:

protected void ExecuteInTransaction(Action action)
{
    using (var transaction = connection.BeginTransaction())
    {
        action.Invoke();
        transaction.Commit();
    }
}

Upvotes: 3

compman2408
compman2408

Reputation: 2509

Take the throw; code out of the catch block. If you want to know when the code goes into the catch block then use a breakpoint or Debug.WriteLine().

The catch block of a try/catch doesn't not catch exceptions thrown in itself. So the throw; code is creating an unhandled exception. If you want to test the code that's in the catch block then add the throw; code to the end of the try block.

EDIT: I didn't realize OP wanted the exception to propogate up the chain. He mentioned nothing about the exception being propagated up the chain and his code shows no support for an exception that propagates up since he doesn't show the code that calls this ExecuteInTransaction(Action) method. A catch block can rethrow the exception that it catches. I agree with that. However the code catch(Exception){ throw; } will not re-enter the same catch block. If it would that would create an infinite loop and that's not what happens. If there is a try/catch block surrounding this then the outer catch block will catch the rethrown exception however his code only includes a single catch block. Therefore when it tries to rethrow the exception there is nothing to catch it and the application breaks.

Try something like this:

private void Main()
{
    // Instantiate action variable. I know this wouldn't work, but it's just for show.
    Action myAction;
    try
    {
        ExecuteInTransaction(myAction);
    }
    catch(Exception ex)
    {
        Debug.WriteLine("Error happened and transaction rolled back. " + ex.Message);
    }
}

protected void ExecuteInTransaction(Action action)
{
    using (SQLiteTransaction transaction = connection.BeginTransaction())
    {
        try
        {
            action.Invoke();
            transaction.Commit();
        }
        catch(Exception ex)
        {
            transaction.Rollback();
            throw ex;
        }
    }
}

Upvotes: -1

Pat Hensel
Pat Hensel

Reputation: 1374

Does anybody know why this is happening, and how can I avoid it?

Its hard to say without seeing your call stack.

In general there are 3 possible options:

  1. The exception is being caught higher up the stack.

  2. There's a kernal mode system call somewhere in your call stack and the exception gets swallowed. This only happens when running a 32 bit application on 64 bit windows. The most notable example being an exception thrown in the OnLoad() method of a Form. See VS2010 does not show unhandled exception message in a WinForms Application on a 64-bit version of Windows for more info.

  3. The exception is being thrown on a ThreadPool thread and not being propagated back to the main thread.

Upvotes: 0

bmm6o
bmm6o

Reputation: 6515

Are you sure there's a catch up the stack that can handle this error? The dialog you showed is what you see when an Exception goes unhandled off the top of your program's Main method. The debugger message actually tells you that it was unhandled, so there is no next statement to step to.

Upvotes: 1

Related Questions