Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DirectShow内存没有';不能适当地释放_C#_Memory_Marshalling_Directshow_Directshow.net - Fatal编程技术网

C# DirectShow内存没有';不能适当地释放

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和directshow.net库时遇到了内存问题

目标是复制一个AVI文件,并且一切正常,除了调用Marshal.ReleaseComObject后内存根本不会释放

我在创建图表时遵循的几个步骤

  • 创建IFilterGraph2对象
  • 创建ICaptureGraphBuilder2
  • 集滤波器
  • 使用IFilterGraph2.AddSourceFilter添加源筛选器
  • 创建和配置ISampleGrabber
  • 添加ISampleGrabber
  • 渲染流
  • 此时,如果我从图中移除过滤器并调用ISampleGrabber上的Marshal.ReleaseComObject,如果FilterGraph2和ICaptureGraphBuilder2释放,内存仍然保留,并且永远不会卸载

    问题是,如果我在不关闭整个进程的情况下播放许多文件,我最终会收到来自Com对象的80004001错误,这听起来有点奇怪

    提前感谢您的阅读和任何进一步的建议


    编辑:从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是一个模块变量,而不是本地变量,它是在渲染完成并收到适当的媒体事件后发布的