1
votes

I am working on an Excel add-in in C# that displays a progress bar while running a simulation. I want a BackgroundWorker to run the simulation asynchronously and report back the progress to the progress bar form.

The simulation method needs a reference to the current Excel COM application. I have a class called ThisAddin which implements the ExcelDna.Integration.IExcelAddIn interface and has a static property which returns the application.

However as soon as the background worker attempts to use the application in any way, it will leave the Excel process running even after I quit Excel.

For example if I simply set a property in the Excel app like so:

void backgroundworker_DoWork(object sender, DoWorkEventArgs e)
{
    ThisAddIn.App.DisplayStatusBar = true;
}

Then after running the add-in and closing Excel, I will still have an Excel process running in my task manager.

Is there a way to ensure that the process gets killed? Am I somehow creating another instance of the application in the background worker? I don't understand because if I call quit() on the app from within the background worker, it will close the entire application and the process will STILL be left running!

When the background worker finishes, I've made sure to call dispose() on it and abort its current thread. I've use an "AbortableBackgroundWorker" class as suggested here. But that still doesn't fix my problem.

1
Simplest way to solve your problem is to do what BGW was meant to do, only access the "UI" in event handlers for the ProgressChanged or RunWorkerCompleted event handlers. A correctly placed GC.Collect() is an alternative.Hans Passant

1 Answers

1
votes

The problem is that you are holding onto Excel objects longer than you think you are. Two options I've seen used successfully:

  1. Use Marshal.ReleaseComObject on each and every Excel object you touch.
  2. Create a new AppDomain and do all of your Excel work in it. Then unload the entire AppDomain, which ensures that any lingering objects will be disposed of.

Option 1 is easier to understand, but more brittle and error prone.