Могу ли я ссылаться / использовать COM-объекты в моем финализаторе?
У меня есть тип COM (созданный с помощью tlbimp.exe) и класс C#, который обертывает этот объект. Я хочу выполнить некоторую очистку в финализаторе для моей оболочки C#. Следуя инструкциям здесь, я мог бы написать что-то вроде этого:
public class MyClass : IDisposable
{
private IMyComObject comObject;
public MyClass()
{
comObject = new MyComObject();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
// Be tollerant of partially constructed instances
if (comObject != null)
{
comObject.Cleanup();
// Account for object being disposed twice
comObject = null;
}
}
// Other bits go here...
}
Я знаю, что финализаторы могут работать в любом порядке, и поэтому я не должен пытаться использовать какой-либо объект, который реализует финализатор, однако, насколько я могу сказать, сгенерированные tlbimp COM-типы не реализуют финализатор, и поэтому вышеприведенное должно быть в порядке.
Однако я не смог найти никакой официальной документации по этому вопросу, поэтому мой вопрос: безопасно ли ссылаться и использовать COM-объекты в финализаторе?
1 ответ
Я создал абстрактный класс обертки com, из которого я извлекаю все свои классы обертки com. Я работаю очень хорошо. Мой оригинальный код VB, так как мне нужно позднее связывание. Остальная часть моего приложения написана на C#.
public abstract class ComWrapper : IDisposable
{
protected internal object _comObject;
protected ComWrapper(object comObject)
{
_comObject = comObject;
}
#region " IDisposable Support "
private bool _disposed = false;
protected virtual void FreeManagedObjects()
{
}
protected virtual void FreeUnmanagedObjects()
{
ReleaseComObject(_comObject);
}
private void Dispose(bool disposing)
{
if (!_disposed) {
if (disposing) {
FreeManagedObjects();
}
FreeUnmanagedObjects();
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected override void Finalize()
{
Dispose(false);
base.Finalize();
}
#endregion
}
а также
public static class Helpers
{
public static void ReleaseComObject(ref object o)
{
if ((o != null)) {
try {
Marshal.ReleaseComObject(o);
} catch {
} finally {
o = null;
}
}
}
public static string ToDotNetString(object comString)
{
if (comString == null) {
return string.Empty;
}
string s = comString.ToString();
ReleaseComObject(ref comString);
return s;
}
}