Затяжной процесс Excel - PullRequest
0 голосов
/ 31 мая 2018

Я выполняю службу Windows и использую Microsoft.Office.Interop.Excel, чтобы создать новый файл Excel, отредактировать его и сохранить.

После завершения работы с ним и закрытия соответствующих объектов (рабочего листа, рабочей книги), выхода из приложения excel и маршала, освобождающего COM-объекты, процесс все еще продолжается.

    private void doWork()
    {
        var excelApp = new MsExcel.Application();
        var workBooks = excelApp.Workbooks;
        var workbook = excelApp.Workbooks.Add();
        var sheets = workbook.Sheets;
        _worksheet = workbook.Sheets[1];

        //Do Work Here

        _worksheet.SaveAs(filePath);
        workbook.Close(false,System.Reflection.Missing.Value,System.Reflection.Missing.Value);
        workBooks.Close();
        releaseObject(_worksheet);
        releaseObject(sheets);
        releaseObject(workbook);
        releaseObject(workBooks);
        excelApp.Quit();
        releaseObject(excelApp);

    }

    private void releaseObject(object obj)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
            obj = null;
        }
        catch (Exception ex)
        {
            _log.Error($"Unable to release object {obj} Error:" + ex.ToString());
            obj = null;
        }
        finally
        {
            GC.Collect();
        }
    }

Iвидел пару других постов, в которых предлагалось выпустить объекты, а также ссылки на рабочие книги и листы.Не уверен, почему это все еще не работает.

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Вы не должны вызывать ReleaseComObject.Это старая история о женах, которая началась давно, но она неверна .

Если вы видите, что экземпляры Excel держатся вокруг него, это, вероятно, означает, что ваша программа завершилась без запуска сборщиков мусора и ссылок, которые все еще хранятся в com-объектах.Лучший способ решить вашу проблему - полностью избавиться от функции релиза, а затем вызвать GC.Collect() после возврата метода doWork().

private void doWork()
{
    try
    {
        doWorkImpl();
    }
    finally
    {
        GC.Collect(); //The GC collect needs to be here, after the scope of doWorkImpl ends.
        GC.WaitForPendingFinalizers(); //The excel instance gets closedin the finalizer.
    }
}

private void doWorkImpl()
{
    var excelApp = new MsExcel.Application();
    var workBooks = excelApp.Workbooks;
    var workbook = excelApp.Workbooks.Add();
    var worksheet = workbook.Sheets[1]; //This needs to be a local variable, not a class variable.

    //Do Work Here

    worksheet.SaveAs(filePath);
    workbook.Close(false,System.Reflection.Missing.Value,System.Reflection.Missing.Value);
    workBooks.Close();
    excelApp.Quit();

}

Это должно привести к тому, что экземпляр excel будет работать до тех пор, покаисключение не было выдано, и excelApp.Quit() успешно вызван.

Однако, если вы работаете только с файлами xlsx вместо файлов xsl, я бы сильно рекомендовал бы отойтииз com-взаимодействия и просто используйте , Microsoft SDK предоставляет для непосредственного взаимодействия с файлами .xlsx.

0 голосов
/ 31 мая 2018

Microsoft в настоящее время не рекомендует и не поддерживает автоматизацию приложений Microsoft Office из любых необслуживаемых, неинтерактивных клиентских приложений или компонентов (включая ASP, ASP.NET, DCOM и NT Services), поскольку Office может работать нестабильно.поведение и / или взаимоблокировка при работе Office в этой среде.

Если вы создаете решение, работающее в контексте на стороне сервера, вы должны попытаться использовать компоненты, которые были сделаны безопасными для автоматического выполнения.Или вы должны попытаться найти альтернативы, которые позволяют хотя бы части кода работать на стороне клиента.Если вы используете приложение Office из серверного решения, приложению не хватит многих необходимых возможностей для успешной работы.Кроме того, вы будете рисковать стабильностью вашего общего решения.Подробнее об этом читайте в статье Особенности серверной автоматизации Office .

В качестве обходного пути вы можете рассмотреть возможность использования One XML SDK или любых других сторонних компонентов, предназначенных для выполнения на стороне сервера или службы.

...