An object-oriented programming language developed by Microsoft that can be used in .NET.
Excel remains as a background task because the Runtime Callable Wrapper (RCW) for the COM objects is still holding references to Excel. Simply setting variables to Nothing and calling ReleaseComObject once is not always enough.
Use the pattern from the documented resolution: explicitly release each COM object in the correct order, looping ReleaseComObject (or using FinalReleaseComObject in .NET 2.0+), and only then force garbage collection if needed.
Example adapted to VB.NET:
Private Sub NAR(ByVal o As Object)
Try
While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
End While
Catch
Finally
o = Nothing
End Try
End Sub
Private Sub BGWLoadData_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) _
Handles BGWLoadData.RunWorkerCompleted
LblProgress.Text = ""
TxtQuery.Enabled = True
Label1.Text = "Start Typing:"
' Release in reverse order of creation/use
NAR(xlWorkSheet)
xlWorkBook.Close(False)
NAR(xlWorkBook)
' If you have xlWorkBooks collection, release it too
' NAR(xlWorkBooks)
xlApp.Quit()
NAR(xlApp)
' Optional: if Excel still does not exit
GC.Collect()
GC.WaitForPendingFinalizers()
End Sub
Key points:
- Release every Excel COM object that was created (Application, Workbooks, Workbook, Worksheet, etc.).
- Release them in reverse order of creation (child objects first, then parent, then Application).
- Use a loop with
Marshal.ReleaseComObject(orMarshal.FinalReleaseComObjectin .NET 2.0 and later) to ensure all RCW references are released. - Only after all COM objects are released, optionally call
GC.Collect()andGC.WaitForPendingFinalizers()if Excel still does not shut down.
Following this pattern causes the Excel process to exit once the last COM reference is released.
References: