是否未释放COM对象未分配给var?

时间:2016-11-14 15:49:29

标签: c# excel-interop comobject unmanagedresources com-object

如果我使用像这样的代码

,将释放所有非托管COM对象
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);

如果有文档,请发送回答链接。

1 个答案:

答案 0 :(得分: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());