2016-11-14 18 views
3

Будет все неуправляемые COM объекты, выпущенные в случае, если я использую такой кодНе имеет значения COM-объект, не присвоенный var, не выпущен?

var worksheet = new Application().Workbooks.Add().Worksheets.Add(); 
Marshal.ReleaseComObject(worksheet); 

вместо кода, как этот

var excel = new Application(); 
var workbook = excel.Workbooks.Add(); 
var worksheet = workbook.Worksheets.Add(); 
Marshal.ReleaseComObject(excel); 
Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(worksheet); 

?

Если есть какая-либо документация, пожалуйста, отправьте ссылку в ответ.

+0

Возможно, использовать FinalReleaseComObject? https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject(v=vs.110).aspx – EJoshuaS

+4

Ничего не достаточно. Никогда не пишите ручной код управления памятью, вы ошибетесь и не сможете его отладить. http://stackoverflow.com/a/25135685/17034. –

+0

FinalReleaseComObject по-прежнему выпускает ссылки только на конкретный COM-объект не на все ссылки на весь COM-объект. –

ответ

1

На самом деле оба примера кода оставят процесс Excel в фоновом режиме. Например, вам нужно вызвать Application.Quit() на объект приложения. Следующие работы:

private static void DoExcel() 
    { 
     var application = new Application(); 
     var workbook = application.Workbooks.Add(); 
     var worksheet = workbook.Worksheets.Add(); 

     // Name that this will be saved as 
     string name = workbook.FullName + ".xlsx"; 

     string fullPath = Path.Combine(Directory.GetCurrentDirectory(), name); 
     // If a file of the same name exists, delete it so that we won't be prompted if 
     // we want to overwrite it when we save 
     if (File.Exists(fullPath)) 
      File.Delete(fullPath); 

     // Save the workbook - otherwise we may be prompted as to whether we want to save when we go to quit 
     workbook.Save(); 

     // Quit the application 
     application.Quit(); 

     // Release the references 
     Marshal.ReleaseComObject(worksheet); 
     Marshal.ReleaseComObject(workbook); 
     Marshal.ReleaseComObject(application); 

     // Release the .NET reference and run the garbage collector now to make sure the application is closed immediately 
     worksheet = null; 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
    } 

Несколько других хороших вещей, чтобы помнить: я не использовал его здесь, но есть Marshal.FinalReleaseComObject method, что очень полезно в таких случаях. Кроме того, опять-таки я не использовал это в моем примере кода, но метод Marshal.ReleaseComObject возвращает текущее значение счетчика, так что вы всегда можете сделать релиз в цикле, если вы хотите, чтобы убедиться, что счетчик достиг нуля:

while (Marshal.ReleaseComObject(comObject) > 0) { } 

Вы также можете использовать это для целей отладки - например

int count = Marshal.ReleaseComObject(comObject); 
Trace.TraceInformation("Current COM object reference count: " + count.ToString()); 
+1

На самом деле мне нужно, чтобы Excel работал, пока он не будет закрыт при взаимодействии с пользователем. –

+1

@ Uzivatel828 Вы имеете в виду взаимодействие с вашей программой? Если это так, вы не хотите выпускать объект приложения, но тогда вам нужно будет сделать все с помощью Save and Quit, когда вы хотите закрыть его. – EJoshuaS

+0

Нет гарантии того, что программа будет работать во времени, когда Excel будет закрыт, поэтому все ссылки должны быть выпущены сразу после работы. –

 Смежные вопросы

  • Нет связанных вопросов^_^