Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you catch a RaceOnRCWCleanup exception

My colleague wrote this code "closeConnection()" below, and its throwing an exception of type:

RaceOnRCWCleanup was detected

An attempt has been made to free an RCW that is in use. The RCW is in use on the active thread or another thread. Attempting to free an in-use RCW can cause corruption or data loss.

private static void closeConnection()
    {
        if(connection != null)
        {
            try
            {
                connection.Close(); // <-- this is the problem
            }
            catch(Exception)
            {
            }

            connection = null;
        }
    }

Since this code is wrapped in a try { } catch { } block it leads me to conclude that you cannot catch this type of exception. Is this the case?

like image 339
patrick Avatar asked Jan 20 '26 11:01

patrick


2 Answers

It is not an exception, it is a debugger warning. It is one of the "managed debugging assistants", designed to catch common mistakes that can cause very difficult to diagnose problems later. So no, you cannot catch it with try/catch. You turn it off with Debug + Exceptions, Managed Debugging Assistants, Thrown checkbox for "RaceOnRCWCleanup".

It can be a false alarm, but you ought to fret about this a bit. The generic diagnostic is that the connection.Close() call is causing a COM object to be released. But it is returning to code that got started by that same COM object, typically due to an event. Which means that it may return to code inside the COM server that is part of a now destroyed COM object. It usually gives a loud bang if that's something the server cannot deal with, typically with a completely undiagnosable AccessViolation. If it doesn't go bang and you tested this thoroughly then go ahead and turn the warning off. Or find a way to call Close() later, check this answer for an example.

like image 154
Hans Passant Avatar answered Jan 23 '26 01:01

Hans Passant


You have probably have a race condition, multiple threads can enter your method at the same time. You need to lock so that 2 threads do not enter the same code at the same time e.g.

public static classs SomeClass
{

private static object locker;

private static void closeConnection()
    {
        if(connection != null)
        {
            lock(locker)
            {
                if(connection != null) //might have been set to null by another thread so need to check again
                {
                    try
                    {
                        connection.Close(); // <-- this should work now
                    }
                    catch(Exception)
                    { //Don't swallow an exception here
                    }

                    connection = null;
                }
            }
       }
}

RaceOnRCWCleanup is not an exception so you cannot catch it, it is something happening outside the CLR that triggers a debugger attachment request.

like image 45
Ben Robinson Avatar answered Jan 23 '26 00:01

Ben Robinson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!