簡體   English   中英

處置靜態對象C#

[英]Disposing static objects c#

我有一個靜態類,可實現與Excel相關的功能(類庫)。

此dll是作為對其他應用程序的引用而添加的,我正在嘗試使用這些功能。

我知道在主程序終止時會放置靜態對象。 我可以以某種方式處置它嗎?

在我的代碼中,如果我調用CreateExcelDocument(excelFile) ,則Excel實例在后台運行(我可以在Windows的進程管理器中看到它)。 但是,當我調用DisposeExcelDocument(); 該實例仍然存在。 我該如何處置?

我的目標是一個一個地打開多個Excel文件,從當前打開的文件中創建圖形,然后關閉並繼續到下一個文件。 可能嗎?

這是代碼:

public static class ExcelUtils
{
    #region Private Members

    private static Application m_excelApp;
    private static Workbook m_excelWorkBook;
    private static Worksheet m_excelWorkSheet;

    #endregion Private Members

    #region Properties

    public static Worksheet ExcelWorkSheet
    {
        get { return m_excelWorkSheet; }
        set { m_excelWorkSheet = value; }
    }

    #endregion Properties

    #region Public Functions

    public static void CreateExcelDocument(string excelFile)
    {
        try
        {
            m_excelApp = new Application();
            m_excelApp.DisplayAlerts = false;
            m_excelWorkBook = m_excelApp.Workbooks.Add(Type.Missing);
            m_excelWorkSheet = (Worksheet)m_excelApp.ActiveSheet;
            m_excelApp.DefaultSheetDirection = (int)Constants.xlLTR;
            m_excelWorkSheet.DisplayRightToLeft = false;

            if (excelFile.CompareTo("") != 0)
            {
                m_excelWorkBook = m_excelApp.Workbooks.Open(excelFile);
                m_excelWorkSheet = (Worksheet)m_excelApp.Worksheets.get_Item(1);
                m_excelWorkSheet.Columns.ClearFormats();
                m_excelWorkSheet.Rows.ClearFormats();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return;
        }
    }
    public static void DisposeExcelDocument()
    {
        try
        {
            m_excelApp.Quit();
            ReleaseObject(m_excelWorkSheet);
            ReleaseObject(m_excelWorkBook);
            ReleaseObject(m_excelApp);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return;
        }
    }

    public static void ReleaseObject(object currentObject)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(currentObject);
            currentObject = null;
        }
        catch (Exception ex)
        {
            currentObject = null;
            Console.WriteLine(ex.ToString());
            return;
        }
        finally
        {
            GC.Collect();
        }

    }

    public static uint GetNumberOfRowsOrCols(string excelFile, bool getRows)
    {
        CreateExcelDocument(excelFile);

        uint rowColNum = 0;

        if (getRows)
            rowColNum = (uint)m_excelWorkSheet.UsedRange.Rows.Count;
        else
            rowColNum = (uint)m_excelWorkSheet.UsedRange.Columns.Count;

        DisposeExcelDocument();

        return rowColNum;
    }

    #endregion Public Functions
}

首先,我同意關於將其作為非靜態類的評論。

但是就您的問題而言,垃圾收集器不會收集對象,因為您沒有將class成員設置為null,而只是在ReleaseObject方法中設置了本地引用。

要使更改最少的類成員為空,將把currentObject參數作為ref傳遞給ReleaseObject方法,並且必須使用泛型而不是object數據類型。 因此該方法將變為:

public static void ReleaseObject<T>(ref T currentObject) where T : class

並調用此方法,您將進行如下更改:

ReleaseObject(ref m_excelWorkSheet);

您可以按原樣保留ReleaseObject方法的主體,但我認為不需要調用GC.Collect() ,如果確實需要,則在對所有對象都調用ReleaseObject之后,最后僅從DisposeExcelDocument調用一次對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM