Использование объектов Wrapper для правильной очистки объектов взаимодействия Excel

Все эти вопросы:

Excel 2007 зависает при закрытии через .NETКак правильно очистить объекты взаимодействия Excel в C #Как правильно очистить объекты взаимодействия в C #

бороться с проблемой того, что C # не освобождает объекты COM COM должным образом после их использования. Есть в основном два направления работы над этой проблемой:

Убейте процесс Excel, когда Excel больше не используется.Позаботьтесь о том, чтобы вначале явно назначить каждый COM-объект, используемый переменной, и гарантировать, что в конечном итоге Marshal.ReleaseComObject будет выполняться для каждого.

Некоторые утверждают, что 2 слишком утомительно, и всегда есть некоторая неопределенность, если вы забудете придерживаться этого правила в некоторых местах кода. Тем не менее, 1 кажется мне грязным и подверженным ошибкам, также я предполагаю, что в ограниченном окружении попытка уничтожить процесс может вызвать ошибку безопасности.

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

Каждый класс Excel Interop имеет свой прокси, который оборачивает объект этого класса.Прокси-сервер освобождает COM-объект в своем финализаторе.Прокси имитирует интерфейс класса Interop.Любые методы, которые изначально возвращали COM-объект, изменяются для возврата прокси. Другие методы просто делегируют реализацию внутреннему COM-объекту.

Пример:

public class Application
{
    private Microsoft.Office.Interop.Excel.Application innerApplication
        = new Microsoft.Office.Interop.Excel.Application innerApplication();

    ~Application()
    {
        Marshal.ReleaseCOMObject(innerApplication);
        innerApplication = null;
    }

    public Workbooks Workbooks
    {
        get { return new Workbooks(innerApplication.Workbooks); }
    }
}

public class Workbooks
{
    private Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks;

    Workbooks(Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks)
    {
        this.innerWorkbooks = innerWorkbooks;
    }

    ~Workbooks()
    {
        Marshal.ReleaseCOMObject(innerWorkbooks);
        innerWorkbooks = null;
    }
}

Мои вопросы к вам, в частности:

Кто считает это плохой идеей и почему?Кто считает эту идею ужасной? Если да, то почему никто еще не внедрил / не опубликовал такую ​​модель? Это только из-за усилий, или я пропускаю проблему убийства с этой идеей?Разве невозможно / плохо / подвержен ошибкам делать ReleaseCOMObject в финализаторе? (Я видел только предложения поместить его в Dispose (), а не в финализатор - почему?)Если подход имеет смысл, есть предложения по его улучшению?

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

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