Могу ли я создать обобщенный метод для освобождения COM-объектов? - PullRequest
1 голос
/ 29 августа 2010

Учитывая следующий код, будет ли метод ReleaseCOMObj () освободить исходный COM-объект или он неявно создаст копию и выпустит эту копию?к статическому.См. Передача COM-объектов в качестве параметров в C # для объяснения того, почему параметр Object не может быть ref Object obj.

Ответы [ 2 ]

1 голос
/ 29 августа 2010

Если вы хотите установить ссылку на ноль, вы можете использовать универсальный метод, такой как:

 private static void ReleaseComObj<T>(ref T obj) where T:class  {
        if (obj != null) {
            Marshal.ReleaseComObject(obj);
            obj = null;
        }
    }

Хотя установка ссылки на нуль не требуется. COM-объект будет освобожден в любом случае. См. Документацию для RealeaseComObject () . Вы также можете рассмотреть возможность вызова FinalReleaseComObject () .

Также вы можете создать объект-оболочку, который реализует IDisposable, и использовать блок using для получения освобожденного COM-объекта, даже если есть исключение.

class ComObjectCleanUp : IDisposable {

    private T obj;

    public ComObjectCleanUp(T obj) {
        this.obj = obj;
    }

    public void Dispose() {
        if (obj != null)
            Marshal.FinalReleaseComObject(obj);
    }
}

И твой код становится:

private void TestRelease()
{
    Excel.Workbook workbook = excel.ActiveWorkbook;
    using (var c = new ComObjectCleanUp(workbook))
    {
        // do stuff
    }
}

Хотя я признаю, что это не очень красиво, особенно учитывая количество COM-объектов, на которые вы будете ссылаться при помощи автоматизации Office, но это все равно идея.

1 голос
/ 29 августа 2010

Параметры C # передаются по ссылке .

Следовательно, он освободит исходный объект COM, но не установит исходную переменную на null.

Чтобы установить исходную переменную на null, измените ее на параметр ref, который передает переменную по ссылке.(и вызывать его с ключевым словом ref)

Кроме того, кстати, метод должен быть static, поскольку он не использует this.

...