Как я реализую расположить шаблон в c# при обертывании COM-объекта Interop?

Это - описательная часть URL, который является там для создания его более человеческим описательный, но обязательно не требуясь веб-сервером - в , Что является " slug" в Django? краткий заголовок является 'in-django-what-is-a-slug', но краткий заголовок не используется для определения , страница служила (на этом сайте, по крайней мере)

5
задан Sam 28 July 2009 в 19:51
поделиться

3 ответа

Похоже, вы почти пригвоздили. Я бы вернулся к шаблону, в котором у вас есть защищенное виртуальное удаление, которое принимает логический параметр, указывающий, следует ли удалять управляемые элементы. Таким образом, кто-нибудь, кто придет за вами, продолжит правильно реализовать IDisposable .

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

~MyClass()
{
    this.Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
    // if (disposing)
    // {
    //      // Managed
    // }

    if (comInstance != null)
    {
        comInstance.FreeStuff();
        comInstance = null;
    }

    // base.Dispose(disposing) if required
}
2
ответ дан 14 December 2019 в 04:44
поделиться

Во-первых, я согласен с теми, кто предлагает использовать финализатор в качестве резервной копии, но стараюсь избегать его вызова, явно вызывая myClass.Dispose или используя 'using'.

например

var myClass = new MyClass()
try
{
   //do stuff
}
finally
{
   myClass.Dispose();
}

или

using (var myClass = new MyClass())
{
   //do stuff
}

Marshall.ReleaseComObject

Если вы используете много COM-объектов, я также предлагаю вам использовать Mashall.ReleaseComObject (comObj) для явной очистки ссылок на RCW.

Итак, такой код предложено в другом месте:

if (comInstance != null)
{
    comInstance.FreeStuff();
    comInstance = null;
}

будет выглядеть так:

if (comInstance != null)
{
    comInstance.FreeStuff();

    int count = Marshall.ReleaseComObject(comInstance);
    if (count != 0)
    {
            Debug.Assert(false, "comInstance count = " + count);
            Marshal.FinalReleaseComObject(comInstance);
    }

    comInstance = null;
}

Хотя проверка возвращаемого значения ReleaseComObject () не является строго необходимой, мне нравится проверять ее, чтобы убедиться, что все увеличивается / уменьшается, как ожидалось.

2 точки Правило

Если вы решите использовать это, нужно знать, что может потребоваться рефакторинг некоторого кода, чтобы должным образом освободить ваши COM-объекты. В частности, это то, что я называю правилом двух точек. Любая строка, использующая COM-объекты, содержащие 2 точки, требует пристального внимания. Например,

var name = myComObject.Address.Name;

В этом операторе мы получаем ссылку на COM-объект Address, увеличивающий его счетчик ссылок RCW, но у нас нет возможности вызвать ReleaseComObject. Лучший способ сделать это - разбить его на части (попробуйте .. окончательно опущено для ясности):

var address = myComObject.Address;
var name = address.Name;
MyReleaseComObject(address);  

где MyReleaseComObject - это служебный метод, заключающий в себе мою проверку количества и FinalReleaseComObject () сверху.

3
ответ дан 14 December 2019 в 04:44
поделиться

В конечном итоге вам нужен этот тип шаблона:

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

~MyClass()
{
    Dispose(false);
}

private void Dispose(bool disposing)
{
    if (disposing)
    {
        // Dispose of disposable objects here

    }

    // Other unmanaged cleanup here which will be called by the finalizer
    if (comInstance != null)
    {
         comInstance.FreeStuff();
         comInstance = null;
    }

    // Call base dispose if inheriting from IDisposable class.
    base.Dispose(true);
}

Для получения отличной статьи о том, почему, ознакомьтесь с Правильная реализация IDisposable и шаблона Dispose.

3
ответ дан 14 December 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: