Microsoft.Interop对象不会退出或“释放”

时间:2012-03-02 22:22:06

标签: c# object excel-interop

每次运行此代码时,对象都不会关闭。我仍然在任务管理器中运行excel.exe。即使我设置对象= null,仍然没有。我甚至尝试过使用对象.Quit()方法。

我在这里做错了什么?

    private bool ValidateQM()
    {
        //setup the objects
        Excel.Application oXL = null;
        Excel.Workbook oWB = null;
        Excel.Worksheet oSheet = null;
        int hWnd = 0;

        try
        {

            //Start Excel and get Application object.
            oXL = new Excel.Application();
            hWnd = oXL.Application.Hwnd;
            oXL.Visible = false;

            //Open the workbook.
            oWB = oXL.Workbooks.Open(workingForm, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",true, false, 0, true, false, false);

            //Get the Worksheet
            oSheet = oWB.Worksheets[1];

            //Check the date values

            string mydatetime = oSheet.Cells[5, 33].Text.ToString() + " " + oSheet.Cells[7, 33].Text.ToString();
            string dateofscore = oSheet.Cells[3, 12].Text.ToString();

            DateTime.Parse(mydatetime); //make my string a real boy
            DateTime.Parse(dateofscore);

            // Cleanup 
            GC.Collect();
            GC.WaitForPendingFinalizers();

            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSheet);

            //oWB.Close();
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWB);

            //oXL.Quit();
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oXL);

            return true;
        }

3 个答案:

答案 0 :(得分:1)

当你调用GC.Collect()时,oXL和oWB对象仍在范围内,因此有一个对它们有效的引用。因此,GC.Collect()不会触及它们。如果要确保它们被垃圾收集,请将它们设置为null,这样在调用GC.Collect()时没有活动的引用。此外,您可能希望在活动工作簿上调用Close()并在Excel应用程序上调用Quit()。你也可以用括号{}将所有东西都放在自己的范围内,这样它就会一起超出范围。

        // Cleanup 
        oWB.Close(false);
        oWB = null;
        oXL.Quit();
        oXL = null;
        hWnd = null;
#if (DEBUG_SPEED_UP_GC)
        GC.Collect();
        GC.WaitForPendingFinalizers();
#endif

编辑:请注意,手动调用垃圾回收是一个坏主意。我假设您只是为了调试目的而在GC发生时加速,所以我添加了#if。

答案 1 :(得分:1)

你不是在hWnd = oXL.Application.Hwnd 行中违反“不使用2点”规则吗?有关详情,请参阅Excel interop libraries incompatible with ASP.NET?

答案 2 :(得分:0)

我将假设没有抛出异常,并且您未显示的catch处理程序不会为您的问题做任何恶意处理。

  

我甚至尝试过使用对象的Quit方法

除非有针对此的文档建议,否则我不明白为什么您不会总是致电Quit来表示您已完成申请。

//Start Excel and get Application object. oXL = new
Excel.Application();
hWnd = oXL.Application.Hwnd;
oXL.Visible = false;

没关系,你正在改变你不拥有的窗口的可见性,如果Excel在退出时显示警告会怎样?在父窗口上将Visible设置为false会使其与用户混淆。

出于调试目的,请勿尝试隐藏窗口。

您可以采取哪些措施here来防止Excel产生警告,否则需要互动关注。它的基本要点:

DisplayAlerts = false
AskToUpdateLinks = false
AlertBeforeOverwriting = false
Interactive = false
Visible = false
FeatureInstall = 0 'msoFeatureInstallNone

您正在交互式用户会话中运行您的应用程序,对吗?因为anything else is not supported

  

Microsoft目前不推荐,也不支持,   任何无人值守的Microsoft Office应用程序的自动化,   非交互式客户端应用程序或组件(包括ASP,   ASP.NET,DCOM和NT服务),因为Office可能会出现不稳定   Office在此环境中运行时的行为和/或死锁。