从任务管理器

时间:2015-08-07 21:25:06

标签: c# excel

我在C#和Office 2013中使用Visual Studio 2015社区。

以下代码用于打开和关闭Excel。然后我添加了代码来打开一个特定的工作表,如下面的例2所示。而且,这很有效,Excel正确关闭。

然后我移动了一些东西,但忘了使用ReleaseComObject作为工作表并且Excel保持打开状态,所以我在任务管理器中手动关闭它。

现在,以下示例中的任何一个都无效。在我意外忘记释放COM对象后,Excel永远不会关闭,除非我重启我的机器。

示例1

private bool loadExcel()
{
    // Open Excel
    Excel.Application myApp = new Excel.Application();
    // Hide Excel
    myApp.Visible = false;
    GSIWorkbook = myApp.Workbooks.Open( "D:\\Test.xlsx" );
    // Cleanup
    GSIWorkbook.Close( false );
    // Manual disposal because of COM
    while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( GSIWorkbook ) != 0 )
    { }

    myApp.Application.Quit();
    myApp.Quit();
    while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( myApp ) != 0 )
    { }

    myApp = null;
    GSIWorkbook = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();
    return true;

} // End loadExcel

示例2

private bool loadExcel()
{
    // Open Excel
    Excel.Application myApp = new Excel.Application();
    // Hide Excel
    myApp.Visible = false;
    GSIWorkbook = myApp.Workbooks.Open( "D:\\Test.xlsx" );

    for ( int counter = 1; counter < 100; counter++ )
    {
        try
        {
            GSIWorksheet = GSIWorkbook.Sheets[counter];
            if ( GSIWorksheet.Name == _gsi2Sheet )
                break;
        }
        catch
        {
            continue;
        }
    }

    while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( GSIWorksheet ) != 0 )
    { }

    // Cleanup
    GSIWorkbook.Close( false );
    // Manual disposal because of COM
    while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( GSIWorkbook ) != 0 )
    { }

    myApp.Application.Quit();
    myApp.Quit();
    while ( System.Runtime.InteropServices.Marshal.ReleaseComObject( myApp ) != 0 )
    { }

    myApp = null;
    GSIWorkbook = null;

    GC.Collect();
    GC.WaitForPendingFinalizers();
    return true;
} // End loadExcel

1 个答案:

答案 0 :(得分:3)

如果您向我们展示了您对excel对象的完整用法,我打赌您会发现您违反了2点规则。听起来很荒谬我知道,但我认为你无意中创建了无法通过Excel或GC处理的对象实例,然后它无法正常关闭。 (称为Runtime Callable Wrappers)

当你使用 - 比如说 - 这段代码:

xlWorkBook = xlApp.Workbooks.Add

......你实际上是在造成这个问题。您需要创建一个指向Workbooks的变量并直接使用它并将其丢弃。 链接示例:

Dim xlApp As New Excel.Application
Dim xlWorkBooks As Excel.Workbooks = xlApp.Workbooks
Dim xlWorkBook As Excel.Workbook = xlWorkBooks.Add()

....所有代码,然后

xlApp.Quit()

If Not xlWorkBook Is Nothing Then
    Marshal.FinalReleaseComObject (xlWorkBook)
    xlWorkBook = Nothing
End If
If Not xlWorkBooks Is Nothing Then
    Marshal.FinalReleaseComObject (xlWorkBooks)
    xlWorkBooks = Nothing
End If
If Not xlApp Is Nothing Then
    Marshal.FinalReleaseComObject (xlApp)
    xlApp = Nothing
End If

xlApp.Quit()

详情请见此处:

http://www.siddharthrout.com/2012/08/06/vb-net-two-dot-rule-when-working-with-office-applications-2/