Мога ли да реферирам/използвам 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
Опитахте ли да извикате GC в началото на вашия метод 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