Possible en double:
How to properly clean up Excel interop objects in C#C# Interop: processus Excel ne sortiez après l'ajout d'une nouvelle feuille de calcul au fichier existant
J'ai lu beaucoup des autres threads ici sur la gestion des références COM en en utilisant le .Net-Excel interop pour s'assurer que le processus Excel se termine correctement à la sortie, et jusqu'ici les techniques ont très bien fonctionné, mais j'ai récemment rencontré un problème lors de l'ajout de nouvelles feuilles de calcul à un fichier de classeur existant.
Le code ci-dessous laisse un processus Excel zombie.
Si j'ajoute une feuille de calcul à un fichier de classeur nouvellement créé, il se termine correctement. Si je cours le code excluant la ligne .Add()
, il se termine bien. (Le fichier existant que je suis en train de lire est un fichier vide créé par le code commenté)
Des idées?
//using Excel = Microsoft.Office.Interop.Excel;
//using System.Runtime.InteropServices;
public static void AddTest()
{
string filename = @"C:\addtest.xls";
object m = Type.Missing;
Excel.Application excelapp = new Excel.Application();
if (excelapp == null) throw new Exception("Can't start Excel");
Excel.Workbooks wbs = excelapp.Workbooks;
//if I create a new file and then add a worksheet,
//it will exit normally (i.e. if you uncomment the next two lines
//and comment out the .Open() line below):
//Excel.Workbook wb = wbs.Add(Excel.XlWBATemplate.xlWBATWorksheet);
//wb.SaveAs(filename, m, m, m, m, m,
// Excel.XlSaveAsAccessMode.xlExclusive,
// m, m, m, m, m);
//but if I open an existing file and add a worksheet,
//it won't exit (leaves zombie excel processes)
Excel.Workbook wb = wbs.Open(filename,
m, m, m, m, m, m,
Excel.XlPlatform.xlWindows,
m, m, m, m, m, m, m);
Excel.Sheets sheets = wb.Worksheets;
//This is the offending line:
Excel.Worksheet wsnew = sheets.Add(m, m, m, m) as Excel.Worksheet;
//N.B. it doesn't help if I try specifying the parameters in Add() above
wb.Save();
wb.Close(m, m, m);
//overkill to do GC so many times, but shows that doesn't fix it
GC();
//cleanup COM references
//changing these all to FinalReleaseComObject doesn't help either
while (Marshal.ReleaseComObject(wsnew) > 0) { }
wsnew = null;
while (Marshal.ReleaseComObject(sheets) > 0) { }
sheets = null;
while (Marshal.ReleaseComObject(wb) > 0) { }
wb = null;
while (Marshal.ReleaseComObject(wbs) > 0) { }
wbs = null;
GC();
excelapp.Quit();
while (Marshal.ReleaseComObject(excelapp) > 0) { }
excelapp = null;
GC();
}
public static void GC()
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
Si la méthode GC ne fonctionne pas parce que vous maintenez toujours une référence quelque part. Êtes-vous sûr que c'est tout le code pertinent? –
Oui, je reçois un processus de zombie laissé derrière le code ci-dessus exactement comme écrit – yoyoyoyosef