Могу ли я ссылаться / использовать 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-объекты в финализаторе?


person Justin    schedule 08.11.2011    source источник
comment
Вы пытались вызвать сборщик мусора в начале метода Dispose?   -  person Ventsyslav Raikov    schedule 08.11.2011
comment
Они действительно реализуют финализатор, таким образом освобождаются COM-объекты. Так что нет, это небезопасно.   -  person Hans Passant    schedule 08.11.2011
comment
@HansPassant Раньше я так думал, но я не могу найти никакой документации, в которой говорится об этом, и я также не вижу финализатор в разборке   -  person Justin    schedule 08.11.2011
comment
возможный дубликат Безопасно ли вызывать RCW из финализатор?   -  person Justin    schedule 08.11.2011
comment
Финализатор существует в RCW, созданном CLR. Вы этого не видите.   -  person Hans Passant    schedule 08.11.2011
comment
Боковое примечание: любое необработанное исключение, созданное в коде финализатора, заставит CLR немедленно завершить ваш процесс, поэтому убедитесь, что вы точно понимаете, какие исключения могут быть созданы, и обрабатывать их.   -  person Mahol25    schedule 15.05.2012


Ответы (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;
    }
}
person Olivier Jacot-Descombes    schedule 08.11.2011
comment
На самом деле это не отвечает на мой вопрос (или не компилируется) - person Justin; 08.11.2011