C# DirectShow内存没有';不能适当地释放
我在使用directshow和directshow.net库时遇到了内存问题 目标是复制一个AVI文件,并且一切正常,除了调用Marshal.ReleaseComObject后内存根本不会释放 我在创建图表时遵循的几个步骤C# DirectShow内存没有';不能适当地释放,c#,memory,marshalling,directshow,directshow.net,C#,Memory,Marshalling,Directshow,Directshow.net,我在使用directshow和directshow.net库时遇到了内存问题 目标是复制一个AVI文件,并且一切正常,除了调用Marshal.ReleaseComObject后内存根本不会释放 我在创建图表时遵循的几个步骤 创建IFilterGraph2对象 创建ICaptureGraphBuilder2 集滤波器 使用IFilterGraph2.AddSourceFilter添加源筛选器 创建和配置ISampleGrabber 添加ISampleGrabber 渲染流 此时,如果我从图中移除过
编辑:从directshow.net库示例中添加代码,该示例具有相同的行为
private void SetupGraph(Control hWin, string FileName)
{
int hr;
// Get the graphbuilder object
m_FilterGraph = new FilterGraph() as IFilterGraph2;
// Get a ICaptureGraphBuilder2 to help build the graph
ICaptureGraphBuilder2 icgb2 = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
try
{
// Link the ICaptureGraphBuilder2 to the IFilterGraph2
hr = icgb2.SetFiltergraph(m_FilterGraph);
DsError.ThrowExceptionForHR( hr );
// Add the filters necessary to render the file. This function will
// work with a number of different file types.
IBaseFilter sourceFilter = null;
hr = m_FilterGraph.AddSourceFilter(FileName, FileName, out sourceFilter);
DsError.ThrowExceptionForHR( hr );
// Get the SampleGrabber interface
m_sampGrabber = (ISampleGrabber) new SampleGrabber();
IBaseFilter baseGrabFlt = (IBaseFilter) m_sampGrabber;
// Configure the Sample Grabber
ConfigureSampleGrabber(m_sampGrabber);
// Add it to the filter
hr = m_FilterGraph.AddFilter( baseGrabFlt, "Ds.NET Grabber" );
DsError.ThrowExceptionForHR( hr );
// Connect the pieces together, use the default renderer
hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, null);
DsError.ThrowExceptionForHR( hr );
// Now that the graph is built, read the dimensions of the bitmaps we'll be getting
SaveSizeInfo(m_sampGrabber);
// Configure the Video Window
IVideoWindow videoWindow = m_FilterGraph as IVideoWindow;
ConfigureVideoWindow(videoWindow, hWin);
// Grab some other interfaces
m_mediaEvent = m_FilterGraph as IMediaEvent;
m_mediaCtrl = m_FilterGraph as IMediaControl;
}
finally
{
if (icgb2 != null)
{
Marshal.ReleaseComObject(icgb2);
icgb2 = null;
}
}
}
如果没有相关的代码,很难做很多事情——有很多事情可能是你做错了。内存实际上并不需要卸载。另外,请注意,
Marshal.ReleaseComObject
比您想象的要复杂得多,.NET中的COM对象实际上是被管理的,因此这并不等同于在本机代码()中调用->Release
。将代码缩减到显示问题的最低限度(您通常也可以忽略错误处理),并将其发布到此处。乍一看,您似乎在某处重用托管COM包装器(最终导致80004001或“未实现”)-封送。ReleaseComObject
将彻底破坏这一点。如果您正在进行手动引用计数,请确保实际操作正确-在调用Marshal.ReleaseComObject
后,切勿使用COM包装器。感谢这两种方法,从联机示例中添加了一些代码并以相同的行为操作。我开始猜测dshow现在不是一个好办法。好吧,您在finally中发布了icgb2
,但是RenderStream
方法是异步的-您只需将捕获管脚连接到渲染。因此,在将来的某个时候,当COM对象实际释放时,渲染将无法再正常工作。此外,将icgb2
设置为null是货物培养的标志-因为icgb2
是本地的,所以没有任何区别。原始示例代码是否也显示了该问题?在我看来,它似乎没有坏掉(尽管它充满了货物崇拜和其他错误)。@Luaan是的,它显示了相同的mem错误。与我的代码唯一不同的是,ICaptureGraphBuilder2是一个模块变量,而不是本地变量,它在渲染完成并收到适当的媒体事件后才发布。如果没有相关的代码,很难做很多事情——可能有很多事情是您做错的。内存实际上并不需要卸载。另外,请注意,Marshal.ReleaseComObject
比您想象的要复杂得多,.NET中的COM对象实际上是被管理的,因此这并不等同于在本机代码()中调用->Release
。将代码缩减到显示问题的最低限度(您通常也可以忽略错误处理),并将其发布到此处。乍一看,您似乎在某处重用托管COM包装器(最终导致80004001或“未实现”)-封送。ReleaseComObject
将彻底破坏这一点。如果您正在进行手动引用计数,请确保实际操作正确-在调用Marshal.ReleaseComObject
后,切勿使用COM包装器。感谢这两种方法,从联机示例中添加了一些代码并以相同的行为操作。我开始猜测dshow现在不是一个好办法。好吧,您在finally中发布了icgb2
,但是RenderStream
方法是异步的-您只需将捕获管脚连接到渲染。因此,在将来的某个时候,当COM对象实际释放时,渲染将无法再正常工作。此外,将icgb2
设置为null是货物培养的标志-因为icgb2
是本地的,所以没有任何区别。原始示例代码是否也显示了该问题?在我看来,它似乎没有坏掉(尽管它充满了货物崇拜和其他错误)。@Luaan是的,它显示了相同的mem错误。与我的代码唯一不同的是,ICaptureGraphBuilder2是一个模块变量,而不是本地变量,它是在渲染完成并收到适当的媒体事件后发布的