Я работал с некоторыми интерфейсами DirectShow для воспроизведения цифрового ТВ (DVB-T) с использованием С# и 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
в COM-объекте _transportInformationFilter
и, следовательно, его нужно было бы разделить отдельно. Однако вызов Marshal.ReleaseComObject(connPointContainer)
был виновником, вызывающим отрыв от _transportInformationFilter
от его RCW; удаление этого вызова устраняет проблему.
Учитывая это, , в каких ситуациях мне требуется явно освобождать COM-объекты (используя Marshal.ReleaseComObject
) в С#, чтобы избежать утечки ресурсов?