Как правильно очистить объект взаимодействия Excel в C #, редакция 2012 г.

Я нахожусь в процессе написания приложения на C #, которое откроет электронную таблицу Excel (2007, на данный момент) через взаимодействие, сделаю некоторую магию, а затем закрою. «Магическая» часть нетривиальна, поэтому это приложение будет содержать много ссылок на многие COM-объекты, порожденные Excel.

Я писал подобные приложения раньше (на самом деле, слишком много раз), но я никогда не находил удобного, «приятного запаха» подхода к взаимодействию с COM-объектами. Отчасти проблема в том, что, несмотря на серьезные исследования, я все еще не совсем понимаю COM, а отчасти в том, что оболочки взаимодействия скрывают многое, что, вероятно, не следует скрывать. Тот факт, что от сообщества поступает так много разных, противоречащих друг другу предложений, только усугубляет ситуацию.

Если вы не можете сказать по названию, я провел свое исследование. Название ссылается на это сообщение:
Как правильно очистить объекты взаимодействия Excel?

Впервые заданный в 2008 году, совет был действительно полезным и надежным в то время (особенно бит «Никогда не используйте 2 точки с объектами com»), но теперь кажется устаревшим. В марте 2010 года команда Visual Studio разместила в блоге статью, в которой предупреждала коллег-программистов, что Marshal.ReleaseComObject [is] Считается опасным. В статье упоминались две статьи: WebLog cbrumme> ReleaseComObject и Сопоставление между указателями интерфейса и вызываемыми оболочками времени выполнения (RCW), предполагающее, что люди все время использовали ReleaseComInterop неправильно (cbrumme:" Если вы являетесь клиентским приложением, использующим скромный количество COM-объектов, которые свободно передаются в вашем управляемом коде, вам не следует использовать ReleaseComObject ").

Есть ли у кого-нибудь пример умеренно сложного приложения, предпочтительно использующего несколько потоков, которое может успешно перемещаться между утечками памяти (Excel продолжает работать в фоновом режиме после закрытия приложения) и InvalidComObjectExceptions? I ' m ищет что-то, что позволит использовать COM-объект вне контекста, в котором он был создан, но все еще может быть очищен после того, как приложение завершит работу с ним: гибрид стратегий управления памятью, которые могут эффективно сочетать управляемый / неуправляемый разделять.

Ссылка на статью или учебное пособие, в котором обсуждается правильный подход к этой проблеме, была бы очень ценной альтернативой. Мои лучшие попытки Google-fu вернули явно неправильный подход ReleaseComInterop.


ОБНОВЛЕНИЕ:
(Это не ответ)
Я обнаружил эту статью вскоре после публикации:
VSTO и COM Interop от Джейка Джиннивана

Мне удалось реализовать его стратегию упаковки COM-объектов в классы «AutoCleanup» с помощью метода расширения, и я очень доволен результатом. Хотя он не предоставляет решения, позволяющего COM-объектам пересекать границы контекста, в котором они были созданы, и по-прежнему использует функцию ReleaseComObject, он, по крайней мере, обеспечивает аккуратный и простой в использовании -читайте решение.

Вот моя реализация:

class AutoCleanup<T> : IDisposable {

    public T Resource {
        get;
        private set;
    }

    public AutoCleanup( T resource ) {
        this.Resource = resource;
    }

    ~AutoCleanup() {
        this.Dispose();
    }

    private bool _disposed = false;
    public void Dispose() {
        if ( !_disposed ) {
            _disposed = true;
            if ( this.Resource != null && 
                 Marshal.IsComObject( this.Resource ) ) {
                Marshal.FinalReleaseComObject( this.Resource );
            } else if ( this.Resource is IDisposable ) {
                ( (IDisposable) this.Resource ).Dispose();
            }
            this.Resource = null;
        }
    }

}

static class ExtensionMethods {

    public static AutoCleanup<T> WithComCleanup<T>( this T target ) {
        return new AutoCleanup<T>( target );
    }

}

person JDB still remembers Monica    schedule 01.11.2012    source источник
comment
Пожалуйста, опубликуйте его как ответ, чтобы он помог будущим посетителям   -  person nawfal    schedule 01.11.2012
comment
@nawfal - Это не ответ. Просто добавление.   -  person JDB still remembers Monica    schedule 01.11.2012


Ответы (1)


у вас появилась концепция NetOffice для управления прокси-серверами COM? NetOffice использует классы-оболочки для com-прокси и шаблон IDisposable. NetOffice поддерживает отношения родитель-> потомок для прокси. удалить рабочий лист, и все созданные дочерние элементы из экземпляра (ячейки, стили) и т. д. также были удалены. вы также можете использовать специальное событие или статическое свойство для наблюдения за количеством открытых прокси в вашем приложении.

просто взгляните на этот фрагмент документации: http://netoffice.codeplex.com/wikipage?title=Tec_Documentation_English_Management

вы найдете несколько проектов showstopper для управления прокси-сервером com в папке руководств

person Sebastian    schedule 12.11.2012
comment
Это самый интересный ответ. Я не пробовал, но приму это как решение, основанное на описании. - person JDB still remembers Monica; 08.01.2013
comment
В моем небольшом тесте это сработало и закрыло Excel по завершении. Спасибо! - person sonicbabbler; 09.06.2016