Я работал с некоторыми интерфейсами DirectShow для воспроизведения цифрового телевидения (DVB-T) с использованием C # и DirectShow.Net . Я недавно столкнулся с ошибкой во время выполнения COM object that has been separated from its underlying RCW cannot be used.
Эта ошибка произошла в следующей строке:
_guideData = _transportInformationFilter as IGuideData;
_transportInformationFilter
имеет тип IBaseFilter, COM-объект, ранее назначенный с помощью служебной функции DirectShow.Net.
Я предположил, что ошибка произошла из-за преждевременного освобождения _transportInformationFilter
, и я проследил ее до следующего метода (обработка ошибок удалена):
private void AttachGuideDataEvent()
{
IConnectionPoint connPoint = null;
IConnectionPointContainer connPointContainer = null;
try
{
connPointContainer = _transportInformationFilter as IConnectionPointContainer;
if (connPointContainer == null) /* error */
var guideDataEventGuid = typeof (IGuideDataEvent).GUID;
connPointContainer.FindConnectionPoint(ref guideDataEventGuid, out connPoint);
if (connPoint == null) /* error */
int cookie;
connPoint.Advise(this, out cookie);
if (cookie == 0) /* error */
_persistIGuideDataEventCookie = cookie;
}
finally
{
if (connPointContainer != null)
Marshal.ReleaseComObject(connPointContainer);
if (connPoint != null)
Marshal.ReleaseComObject(connPoint);
}
}
Как я понял, connPointContainer = _transportInformationFilter as IConnectionPointContainer
должен был привести к вызову QueryInterface
для _transportInformationFilter
COM-объекта и, следовательно, должен был бы быть освобожден отдельно. Тем не менее, вызов Marshal.ReleaseComObject(connPointContainer)
был виновником того, что _transportInformationFilter
был отделен от своего RCW; удаление этого вызова решило проблему.
Учитывая это, в каких ситуациях мне необходимо явно освобождать COM-объекты (используя Marshal.ReleaseComObject
) в C #, чтобы избежать утечки ресурсов?