Гарантированное освобождение COM-объекта? - PullRequest
0 голосов
/ 15 мая 2010

Я написал следующий код в предположении, что Excel умрет с Monkey:

class ExcelMonkey
{
    private static Excel.Application xl = new Excel.Application();

    public static bool parse(string filename)
    {

        if (filename.Contains("foo"))
        { 
            var workbook = xl.Workbooks.Open(filename);
            var sheet = workbook.Worksheets.get_Item(1);

            // do stuff

            return true;

        }

        return false;
    }
}

Как мне убедиться, что это так? Нужно ли выпускать workbook и sheet отдельно?

Я хочу иметь Excel в течение всей жизни программы, это огромное улучшение производительности.

Ответы [ 5 ]

2 голосов
/ 15 мая 2010

Нужно ли выпускать книгу и лист отдельно?

Да, любой из них будет поддерживать базовый объект приложения Excel.

Как сделатьконечно это делает?

Marshal.ReleaseComObject сделает это, но после этого убедитесь, что вы не используете ссылки на объект.

1 голос
/ 01 июня 2010

Если вы хотите работать с офисными файлами, я рекомендую вам взглянуть на NPOI lib . Это точечный сетевой порт библиотеки POI для Java, он работает блуждающим при работе с офисными файлами. Нет необходимости в беспорядочном COM, все сделано в коде CLR, все работает как положено.

Я использую его для создания отчетов Excel без проблем. Попробуйте, я уверен, вы не пожалеете об этом. Гораздо лучше, чем использование COM

1 голос
/ 20 мая 2010

В качестве фона, Excel имеет тенденцию генерировать скрытые ссылки за кулисами в зависимости от механизмов по умолчанию COM, используемых для поддержки VBA. Например, вы можете поговорить с «Приложением», и он тихо установит ссылку на COM, от которой вы не сможете отсоединиться.

Вы все еще должны быть очень дотошными со ссылками на COM при программировании Excel.

Это усугубляется тем фактом, что PIA также любит генерировать ссылки за кулисами, и они не убирают эти ссылки должным образом при сборке мусора. Вы должны явно закрыть любую ссылку COM.

1 голос
/ 16 мая 2010

Вот рабочее решение, если кому-то интересно:

class ExcelMonkey
{
    private Excel.Application xl = new Excel.Application();

    ~ExcelMonkey()
    {
        xl.Quit();
        Dispose(false);
    }

    private bool isDisposed = false;


    protected void Dispose(bool disposing)
    {
        Marshal.ReleaseComObject(xl);
        isDisposed = true;
    }

    public bool parse(string filename)
    {
        if (filename.Contains("foo"))                  
        {
            var workbook = xl.Workbooks.Open(filename);
            var sheet = workbook.Worksheets.get_Item(1);

            try
            {
                // do stuff
            }
            finally
            {
                Marshal.ReleaseComObject(sheet);
                Marshal.ReleaseComObject(workbook);
            }
            return true;
        }
        return false;
    }
}
0 голосов
/ 15 мая 2010

в вызове деструктора

xl.Quit ();

...