title: Disposing of COM object from c#
body: <p>I have read several articles/posts on correctly disposing of COM objects when interacting from .NET. Normally i don't have a problem.. but i keep getting orphaned COM objects after closing my following program.I don't know if it has something to do with the addin i am opening. </p>
  
  <pre><code>        Application app = new Application();
          Workbooks wrks = app.Workbooks;
          Workbook wrk = null;
          Workbook wrkAddin = null;
          Sheets shts = null;
          Range rng = null;           
  
          try
          {
              app.ScreenUpdating = true;
              app.Visible = true;
              app.DisplayAlerts = false; // stop any dialog boxes appearing.. such as save or debug when loading bloomberg addin.
              wrk = wrks.Open(Filename: MasterPriceFiles.Properties.Resources.strETFDataFullPath, ReadOnly: false,Editable: true, IgnoreReadOnlyRecommended: true);
              Thread.Sleep(500);
              wrkAddin = wrks.Open(Filename: MasterPriceFiles.Properties.Resources.strBloombergAddinPath); // have to explicitly open the bloomberg addin
              app.Visible = true;
              Thread.Sleep(50000);
              shts = wrk.Worksheets;
              foreach (Worksheet sht in shts)
              {
                  rng = sht.UsedRange;
                  rng.Copy();
                  rng.PasteSpecial(XlPasteType.xlPasteValues);
                  Marshal.ReleaseComObject(rng);
                  Marshal.ReleaseComObject(sht);
              }
              app.Visible = false;
              app.DisplayAlerts = false;
              Thread.Sleep(500);
              wrk.SaveAs(Filename: MasterPriceFiles.Properties.Resources.strETFDataMacroFreeFullPath, ConflictResolution: XlSaveConflictResolution.xlLocalSessionChanges, AccessMode: XlSaveAsAccessMode.xlNoChange);
              Console.WriteLine("Successfully saved ETF price data sheet at . " + DateTime.Now.ToString());
  
  
          }
          catch(Exception ex)
          {
              Console.WriteLine("Error refreshing ETF price date. " + ex.Message);
          }
          finally
          {
              if (rng != null) Marshal.FinalReleaseComObject(rng);
              if (shts != null) Marshal.FinalReleaseComObject(shts);
              wrk.Close(SaveChanges: false);
              if (wrk != null) Marshal.FinalReleaseComObject(wrk);
              wrkAddin.Close(SaveChanges: false);
              if (wrkAddin != null) Marshal.FinalReleaseComObject(wrkAddin);
              if (wrks != null) Marshal.FinalReleaseComObject(wrks);
              app.Quit();
              if (app != null) Marshal.FinalReleaseComObject(app);
              GC.Collect();
              GC.WaitForPendingFinalizers();
              GC.Collect();
              GC.WaitForPendingFinalizers();
          }
  </code></pre>