Как правильно очистить объект взаимодействия Excel в C #, выпуск 2012
Я нахожусь в процессе написания приложения на C #, которое откроет электронную таблицу Excel (на данный момент 2007) через взаимодействие, сделает немного магии, а затем закроет. "магия» Часть не является тривиальной, поэтому это приложение будет содержать множество ссылок на многие COM-объекты, созданные в Excel.
Я написал такое заявление раньше (на самом деле слишком много раз), но ямы никогда не находили удобного "хороший запах" подход к взаимодействию с COM-объектами. Проблема отчасти в том, что, несмотря на значительные исследования, я до сих пор неЯ не совсем понимаю COM и частично, что упаковщики взаимодействия скрывают многое, что, вероятно, не должнобыть скрытым Тот факт, что в сообществе так много разных противоречивых предложений, только усугубляет ситуацию.
В случае, если вы можетене могу сказать из названия, яя сделал мое исследование Название ссылается на этот пост:
Как правильно очистить объекты взаимодействия Excel?
Впервые спросили в 2008 году, совет был действительно полезным и твердым в то время (особенноНикогда не используйте 2 точки с ком объектами " немного) но сейчас кажется устаревшим. В марте 2010 года команда Visual Studio опубликовала статью в блоге, предупреждающую коллег-программистов о том, чтоMarshal.ReleaseComObject [is] считается опасным, Статья ссылается на две статьи,cbrumme»s WebLog> ReleaseComObject а такжеОтображение между указателями интерфейса и вызываемыми обертками во время выполнения (RCW), предполагая, что люди все время неправильно использовали ReleaseComInterop (cbrumme: "Если вы являетесь клиентским приложением, использующим небольшое количество COM-объектов, которые свободно передаются в вашем управляемом коде, вы не должны использовать ReleaseComObject ").
У кого-нибудь есть пример умеренно сложного приложения, предпочтительно с несколькими потоками, которое может успешно перемещаться между утечками памяти (Excel продолжает работать в фоновом режиме после закрытия приложения) и InvalidComObjectExceptions? Я'Я ищу что-то, что позволит использовать COM-объект вне контекста, в котором он был создан, но все еще может быть очищен после завершения работы приложения: гибрид стратегий управления памятью, которые могут эффективно охватывать управляемый / неуправляемый делить.
Ссылка на статью или учебник, в котором обсуждается правильный подход к этой проблеме, была бы очень ценной альтернативой. Мои лучшие попытки Google-фу вернули явно неверный подход ReleaseComInterop.
ОБНОВИТЬ:
(Это не ответ)
Я обнаружил эту статью вскоре после публикации:
VSTO и COM Interop от Джейка Джиннивани
мы смогли реализовать его стратегию обёртывания COM-объектов в "автоочистки» классы через метод расширения, и яЯ очень доволен результатом. Хотьон не предоставляет решения, позволяющего COM-объектам пересекать границы контекста, в котором они были созданы, и по-прежнему использует функцию ReleaseComObjectэто, по крайней мере, обеспечивает аккуратное и легкое для чтения решение.
Вот'моя реализация:
class AutoCleanup : 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 WithComCleanup( this T target ) {
return new AutoCleanup( target );
}
}