Могу ли я ссылаться / использовать 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;
    }
}
Другие вопросы по тегам