Исключение использования «2 точек» при использовании Excel Interop Com Objects - C #

У меня проблемы с выпуском Excel Interop Com Objects, что приводит к сбою приложения c # при попытке сохранить, а затем закрыть книгу Excel, созданную с помощью Excel Interop. Я чувствую, что проблема в том, что в некоторых случаях я использую2 точки с COM-объектами Excel взаимодействия, которые из того, что яЧтение запрещено. Я удалил 2 точки из большинства строк кода, но у меня возникла проблема с поиском способа воссоздать следующие строки кода, чтобы они использовали только одну точку. Если у кого-то есть какие-либо предложения, я был бы очень признателен.

workbook = (Excel.Workbook)app.Workbooks.Open(startForm.excelFileLocation,);

workbook = (Excel.Workbook)app.Workbooks.Add(1);

workSheet_range.Font.Color = System.Drawing.Color.FloralWhite.ToArgb();

workSheet_range.Font.Bold = font;

workSheet_range.Interior.Color = System.Drawing.Color.Red.ToArgb();
 Henrik25 окт. 2012 г., 15:16
 Govert25 окт. 2012 г., 17:08
Вы можете исследовать с помощью NetOffice (netoffice.codeplex.com) как ваша библиотека взаимодействия, а не сборки PIA. NetOffice имеет внутренний механизм отслеживания, который позволяет правильно очищать, не беспокоясь о промежуточных ссылках COM.

Ответы на вопрос(4)

Я бы порекомендовал использовать библиотеку, какNetOffice который позаботится о высвобождении всех ресурсов для вас (так что вы нене нужно беспокоиться обо всех этих вызовах COM Interop) и в качестве бонуса, даст вам intellisense.

Вы можете установить его через NuGet или скачайте сборки с сайта.

Обобщая всю информацию здесь.

Не используйте две точки при назначении.ИспользоватьAutoReleaseComObject учебный класс.Используйте метод ReleaseObject (который использует цикл while), описанный вMicrosoft KB: приложение Office не завершает работу после автоматизации из .NET-клиента.Используйте GC.Collect и GC.WaitForPendingFinalizers.Дон»Не удивляйтесь, если процесс Excel остается активным при отладке, всегда проверяйте, поддерживается ли этот процесс, просто запустив приложение.

например:

using Microsoft.Office.Interop.Excel;
...
var missing = Type.Missing;
using (AutoReleaseComObject excelApplicationWrapper = new AutoReleaseComObject(new Microsoft.Office.Interop.Excel.Application()))
{
    var excelApplicationWrapperComObject = excelApplicationWrapper.ComObject;
    excelApplicationWrapperComObject.Visible = true;

    var excelApplicationWrapperComObjectWkBooks = excelApplicationWrapperComObject.Workbooks;
    try
    {
        using (AutoReleaseComObject workbookWrapper = new AutoReleaseComObject(excelApplicationWrapperComObjectWkBooks.Open(@"C:\Temp\ExcelMoveChart.xlsx", false, false, missing, missing, missing, true, missing, missing, true, missing, missing, missing, missing, missing)))
        {
            var workbookComObject = workbookWrapper.ComObject;
            Worksheet sheetSource = workbookComObject.Sheets["Sheet1"];
            ChartObject chartObj = (ChartObject)sheetSource.ChartObjects("Chart 3");
            Chart chart = chartObj.Chart;
            chart.Location(XlChartLocation.xlLocationAsObject, "Sheet2");

            ReleaseObject(chart);
            ReleaseObject(chartObj);
            ReleaseObject(sheetSource);

            workbookComObject.Close(false);
        }
    }
    finally
    {
        excelApplicationWrapperComObjectWkBooks.Close();
        ReleaseObject(excelApplicationWrapperComObjectWkBooks);

        excelApplicationWrapper.ComObject.Application.Quit();
        excelApplicationWrapper.ComObject.Quit();
        ReleaseObject(excelApplicationWrapper.ComObject.Application);
        ReleaseObject(excelApplicationWrapper.ComObject);

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();    
    }
}

private static void ReleaseObject(object obj)
{
    try
    {
        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) > 0);
        obj = null;
    }
    catch (Exception ex)
    {
        obj = null;
        Console.WriteLine("Unable to release the Object " + ex.ToString());
    }
}

Я знаю, выпуская все объекты, используя GC.Collect и не используя две точки, когда назначение кажется чрезмернымно по крайней мере, когда я закрываю экземпляр Excel, процесс освобождается, я неПрограммно убить процесс Excel!

 Jeremy Thompson03 дек. 2015 г., 03:20
Или даже ClosedXML гораздо проще, чем OpenXML
 Caio Proiete03 дек. 2015 г., 03:13
Я бы порекомендовал использовать NetOffice (netoffice.codeplex.com) вместо того, чтобы делать все это, каждый раз, когда вы хотите что-то сделать с Excel. Смотрите мой ответ ниже.
 Caio Proiete03 дек. 2015 г., 03:23
+1 на ClosedXML (closedxml.codeplex.com) а также, если все, что вам нужно, это чтение / запись файлов XLSX из приложения - нет необходимости иметь Excel на компьютере. Я много работаю с надстройками Excel, где мое приложение работает внутри процесса Excel, поэтому мне действительно нужно взаимодействовать и, следовательно, использовать NetOffice.
Решение Вопроса

Использование двух точек не "запрещен» но это, безусловно, может повлиять на производительность, особенно при работе в тесной петле.

Другточка» это COM-вызов библиотеки Excel, который может быть значительно медленнее, чем обычный доступ к объекту CLR. В общем, вы хотите уменьшить количество вызовов COM до как можно меньшего числа.

Сокращение от двух точек до одной путем разделения на две линии не окажет никакого влиянияесли Вы повторно используете одну и ту же переменную. Например, изменение

workSheet_range.Interior.Color = System.Drawing.Color.Red.ToArgb();

в

var interior = workSheet_range.Interior;
interior.Color = System.Drawing.Color.Red.ToArgb();

буду иметьНУЛЬ влияет на производительность, и может даже бытьоптимизировано» вернуться к оригинальной однолинейной, если вы нет повторно использоватьinterior переменная.

Тем не менее, изменение

var font = workSheet_range.Font;
font.Color = System.Drawing.Color.FloralWhite.ToArgb();
font.Bold = font;

будет на один звонок меньшеworkSheet_range.Font так что вы'увидим дополнительную выгоду.

НИЖНЯЯ ЛИНИЯ

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

 Joe25 окт. 2012 г., 15:39
Основная проблема при использовании 2 точек с InterOp заключается в том, что экземпляр Excel не закрывается при выходе из приложения, он 'как будто этоs создает анонимные объекты, которые не выпускаются GC. Я обычно исправляю эти проблемы, избавляясь от всех двух точек + освобождая объекты, используя System.Runtime.InteropServices.Marshal.ReleaseComObject (xcelObject) для каждого объекта.

Проверьте тип возврата каждой инструкции и разбейте их отдельно.

Ваша первая строка начинается с "app.Workbooks» который возвращает объект типа Workbooks. Затем инструкция Open возвращает Workbook:

workbooks = app.Workbooks;
workbook = workbooks.Open(startForm.excelFileLocation);

Затем вы можете разделить 2-й как это:

workbook = workbooks.add(1);

Это'Можно использовать несколько точек, если вынерасставить» фактические объекты InterOp.

Вот'Полный образец:

Using Excel = Microsoft.Office.Interop.Excel;
public void Read()
{
    Excel.Application xlApp = new Excel.Application();
    Excel.Workbooks xlWorkBooks = xlApp.Workbooks;
    Excel.Workbook xlWorkBook = xlWorkBooks.Open(sourceFile);
    Excel.Worksheet xlWorkSheet = xlWorkBook.Worksheets[ 1 ];

    Excel.Range range = xlWorkSheet.UsedRange;
    range = range.Cells;
    Array myValues = ( Array )range.Value;    //now holds all the data in the sheet

    //The following is to ensure the EXCEL.EXE instance is released...
    //If you edit this code, know that using 2 dots (ex: range.Cells.Value) can create weird stuff!
    xlWorkBook.Close(false);
    xlWorkBooks.Close();
    xlApp.Quit();

    releaseObject(xlWorkSheet);
    releaseObject(xlWorkBook);
    releaseObject(xlWorkBooks);
    releaseObject(xlApp);

    xlWorkSheet = null;
    xlWorkBooks = null;
    xlWorkBook = null;
    xlApp = null;
}

private static void releaseObject( object obj )
{
try
{
    System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
    obj = null;
}
catch (Exception ex)
{
    obj = null;
    Console.WriteLine("Unable to release the Object " + ex.ToString());
}
}
 Joe25 окт. 2012 г., 15:41
Просто убедитесь, что вы недвойная точка» все, чтовключены в сборку Microsoft.Office.Interop.Excel. Я обновил свой пост примером, который включает в себя правильное освобождение объектов.
 Joe25 окт. 2012 г., 18:30
Если вы не отправите свой новый код, мы выиграемя не смогу тебе помочь гораздо дальшеБоюсь. Однако, если вы знаете, что будете работать исключительно с файлами из Office 2007 и более ранних версий, вам следует взглянуть на библиотеку OpenXML, которая позволит вам манипулировать файлами Excel (.xslx, а не .xls) напрямую, без InterOp.msdn.microsoft.com/en-us/library/office/bb448854.aspx
 user154631525 окт. 2012 г., 15:26
Не могли бы вы уточнить и привести пример того, чторасставить» фактический объект InterOp будет выглядеть так. Это такая головная боль.
 user154631525 окт. 2012 г., 18:03
Я попытался удалить двойную точку из следующих строк кода ниже, и это вызвало необработанное исключение. Я убедился, что изменения, внесенные в следующий код, вызвали его, отменив изменения и заставив его работать. Я'я не уверен, что я сделал не так

Ваш ответ на вопрос