0

I've got this code to release some COM Objects in an Excel Interop app:

    . . .
    }
    Marshal.ReleaseComObject(_xlSheet);

    Marshal.ReleaseComObject(_xlSheets);

    _xlBook.Close(false, null, null);
    Marshal.ReleaseComObject(_xlBook);

    _xlApp.DisplayAlerts = false;
    _xlApp.Quit();
    OnChanged(EventArgs.Empty);
} // foreach (DataRowView drv in selectedUnits)
Marshal.ReleaseComObject(_xlApp);

In another place I also release the sheet used there:

Marshal.ReleaseComObject(_xlSheetDelPerf);

This all works just fine, but a Resharper Inspect > Code Issues in Solution unearths "Possible 'null' assignment to entity marked with 'NotNull' attribute" on the two ReleaseComObject() calls to the Excel.Worksheet objects (but not to the Sheet, Workbook, or Application objects). They are defined like so:

using Excel = Microsoft.Office.Interop.Excel;
. . .
private Excel.Application _xlApp;
private Excel.Workbook _xlBook;
private Excel.Sheets _xlSheets;
private Excel.Worksheet _xlSheet;
private Excel.Worksheet _xlSheetDelPerf;

What makes Worksheet so [un]special? More importantly, should I remove the ReleaseComObject() code for them? And use something else instead to release them?

Note: The accepted answer to the question "How to properly clean up Excel interop objects" by VVS here, with 474 upvotes, does show a sheet being released this way...?!?

UPDATE

Okay, I followed MethodMan's advice (who wouldn't, with a moniker like that?) and now I have:

            // Free up resources
            Marshal.ReleaseComObject(_xlSheet);

            Marshal.ReleaseComObject(_xlSheets);

            _xlBook.Close(false, null, null);
            Marshal.ReleaseComObject(_xlBook);

            _xlApp.DisplayAlerts = false;
            _xlApp.Quit();

            _xlSheet = null;
            _xlSheets = null;
            _xlBook = null;
        } //if (_xlSheet != null)
        OnChanged(EventArgs.Empty);
    } // foreach (DataRowView drvu in selectedUnits)
    Marshal.ReleaseComObject(_xlApp);
    _xlApp = null;
} // try
finally
{
    GC.Collect();
}
Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    you should be doing this for all the ComInterop objects `Marshal.ReleaseComObject` also set the object `= null;` then you can have a Finally block and call `GC.Collect` – MethodMan Dec 02 '15 at 22:16
  • If I should be doing this for all the ComInterop objects (which includes Worksheet), why does Resharper single that object out in this way? – B. Clay Shannon-B. Crow Raven Dec 02 '15 at 22:18

0 Answers0