Я пишу класс excel, и я хочу автоматически освободить этот неуправляемый объект. Я использую шаблон IDisposable и пишут методы Dispose. Пример:
class MSExcel : IDisposable
{
ApplicationClass excel;
bool disposed;
public MSExcel()
{
disposed = false;
excel = new ApplicationClass();
}
public void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
}
excel.Quit();
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MSExcel()
{
Dispose(false);
}
}
Но у меня есть классическая ошибка на exc.Quit(). "COM-объект, который был отделен от его базового RCW". Есть ли у меня ошибка в коде?
Как объясняется в моем ответе на ваш другой связанный с нами вопрос здесь, вы не должны предпринимать действия над ссылочными типами из своего финализатора. Вы применяете это, используя параметр bool disposing
вашего метода Disposed(bool)
, как вы это делали. Вы проходите в true
, когда Disposed(bool)
вызывается явно из метода void Dispose()
и передается в false
при вызове из вашего финализатора, который вы также сделали.
Однако вам также необходимо защитить свой вызов до excel.Quit()
, чтобы он не вызывался, когда Disposed(bool)
вызывается через финализатор. То есть вы должны вызывать только excel.Quit()
, если аргумент bool disposing
true
.
Следовательно, код для вашего метода Disposed(bool)
должен выглядеть следующим образом:
public void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
excel.Quit();
}
disposed = true;
}
}
После этого вы можете использовать свой класс "MSExcel" следующим образом:
using (MSExcel msExcel = new MSExcel)
{
// The code calling your 'MSExcel' object goes here.
}
Таким образом, когда ваш код попадает в закрывающий скобок, "}" вашего блока using statement, Dispose метод на вашем классе "MSExcel" будет вызываться автоматически, гарантируя, что excel.Quit()
называется детерминированным, а не из финализатора.
Надеюсь, что это поможет...
Mike