Ссылки на объекты Excel 2010 не опубликованы - PullRequest
3 голосов
/ 27 октября 2010

Следующий пример кода отлично работал в Excel 2007, но когда я установил Excel 2010 (32 бита), процесс Excel.exe оставался открытым, если я не добавил GC.Collect ().Мой простой вопрос: я делаю что-то не так?Мне кажется, что я выпускаю все, что использую.

    public override void Update()
    {

        StatusBox.AddStatus("Opening File " + ImportPath);

        Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
        Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Open(ImportPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
        Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Sheets[1];

        Range rng = ws.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);

        int LastRow = rng.Row;

        StatusBox.AddStatus(LastRow.ToString() + " Rows Found in File");


        StatusBox.AddStatus("Closing File " + ImportPath);

        System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
        rng = null;

        System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
        ws = null;

        wb.Close(true, ImportPath, null);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
        wb = null;

        GC.Collect();

        app.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
        app = null;
    }

1 Ответ

1 голос
/ 28 октября 2010

Вам нужно вызвать оба GC.Collect / GC.WaitForPendingFinalizers и Marshall.FinalReleaseComObject.

Подробнее см. Здесь мой ответ:

Как сделатьПравильно ли я очищаю объекты взаимодействия Excel?

Обратите внимание, что совет (и, по-видимому, самый популярный ответ) «никогда не использовать две точки» в любой заданной команде является действительным, но практически невозможно применить на практике,Если вы допустите какую-либо ошибку в каком-либо месте своего кода, приложение Excel будет зависать, и на планете нет инструмента профилирования, который мог бы вам помочь - вам придется просмотреть весь код на глаз.Для большой базы кода это практически невозможно.

В вашем коде нет вызова GC.WaitForPendingFinalizers после вызова GC.Collect.Это необходимо для обеспечения синхронности вызовов на сборку мусора.(GC.Collect работает в другом потоке, если вы не дождетесь его, коллекция может произойти не по порядку относительно выпусков вашего последующего объекта, и вы захотите выпустить второстепенные COM-объекты, такие как Ranges, first и majorCOM-объекты, такие как «Рабочие книги» и «Приложение», в конце концов.) После вызова GC.Collect и GC.WaitForPendingFinalizers вы захотите вызвать Marshall.FinalReleaseComObject для ваших именованных ссылок.

Короче говоря, стратегия заключается ввызовите GC.Collect и GC.WaitForPendingFinalizers, чтобы освободить COM-объекты, на которые вы не держите ссылку, и вызовите Marshall.FinalReleaseComObject, чтобы освободить COM-объекты, на которые вы действительно держите именованную ссылку.

- Mike

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...