HiveBrain v1.2.0
Get Started
← Back to all entries
debugcsharpMinor

Is brute force the accepted best practice for handling Excel COM 'busy' exceptions?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
handlingexceptionstheforceexcelpracticeacceptedbusyforbrute

Problem

Following on from a question about handling-com-exceptions-busy-codes I would like to know if the following model is the accepted best practice of handling Excel COM busy messages when accessing the Excel COM object model:

private void AskExcelToDoSomething()
{
    bool retry = true;
    do
    {
        try
        {
            // Call Excel OM
            retry = false;
        }
        catch (COMException e)
        {}
    } while (retry);
}


Assuming that IMessageFilter has been implemented and catches the errors for which it is intended and retries, is the above model the 'accepted' way of handling these busy exceptions? If so, is it not vulnerable to hanging if for some reason it keeps being rejected? Is there no better way of doing this that guarantees success?

Solution

You're missing the Thread.Sleep(500); call from the linked post's solution, which is much, much better than what you've posted here:

private void TryUntilSuccess(Action action)
{
    bool success = false;
    while (!success)
    {
        try
        {
            action();
            success = true;
        }

        catch (System.Runtime.InteropServices.COMException e)
        {
            if ((e.ErrorCode & 0xFFFF) == 0xC472)
            {   // Excel is busy
                Thread.Sleep(500); // Wait, and...
                success = false;  // ...try again
            }
            else
            {   // Re-throw!
                throw e;
            }
        }
    }
}


(above code from sepp2k's answer here)


is it not vulnerable to hanging if for some reason it keeps being rejected?

Given that this code is meant to address a COM exception thrown when Excel is busy, it remaining in the loop would mean, well, that Excel is still busy - and possibly hung... in which case, the user will probably lose their patience and kill the application anyway.

The difference between sepp2k's code and the code you're having here, is that you're swallowing all COM exceptions - which is bad. I really don't see a reason not to use the code provided in the post you're following-up on, which filters the error code (if ((e.ErrorCode & 0xFFFF) == 0xC472)) and re-throws all other exceptions, leaving you with a way to exit the loop if you get a COM exception that's saying anything other than Excel is busy.

Code Snippets

private void TryUntilSuccess(Action action)
{
    bool success = false;
    while (!success)
    {
        try
        {
            action();
            success = true;
        }

        catch (System.Runtime.InteropServices.COMException e)
        {
            if ((e.ErrorCode & 0xFFFF) == 0xC472)
            {   // Excel is busy
                Thread.Sleep(500); // Wait, and...
                success = false;  // ...try again
            }
            else
            {   // Re-throw!
                throw e;
            }
        }
    }
}

Context

StackExchange Code Review Q#28680, answer score: 2

Revisions (0)

No revisions yet.