C# C缓冲区图形内存泄漏

C# C缓冲区图形内存泄漏,c#,memory-leaks,gdi,C#,Memory Leaks,Gdi,我的代码具有以下形式: while (Globals.Running) { if ((Form.Visible == false) || (Form.ContainsFocus == false) || (Form.Enabled == false)) { Threading.Thread.Sleep(100); } else { Update(); Draw(); } Applicatio

我的代码具有以下形式:

while (Globals.Running)
{
    if ((Form.Visible == false) || (Form.ContainsFocus == false) || (Form.Enabled == false))
    {
        Threading.Thread.Sleep(100);
    }
    else
    {
        Update();
        Draw();
    }

    Application.DoEvents();
}
当我在任务管理器中查看流程时,我看到所消耗的内存每秒增加8K

如果我注释掉Draw调用,内存是稳定的。因此,内存在Draw中泄漏。下面是该方法的外观:

private static void Draw()
{
    BufferedGraphics.Graphics.Clear(Color.CornflowerBlue);
    //Engine.Draw(BufferedGraphics.Graphics);
    BufferedGraphics.Render();
    ++FPS;
}
所以,即使我不画任何东西,记忆也会丢失。如果我把它注释掉。清除线,它仍然会泄漏。如果我注释掉.Render行,它仍然会泄漏。如果我把这两个都注释掉,它就会停止泄漏

BufferedGraphics在构造函数中初始化如下:

BufferedGraphics = BufferedGraphicsContext.Allocate(Graphics.FromHwnd(Form.Handle), Form.ClientRectangle);

所以,我的问题是,为什么不渲染/清除图形上下文会泄漏内存?或者这里还有其他原因吗?

不要使用application.doEvents!在不同线程上操作时,使用调度程序更新UI,这样可以防止UI阻塞,更改不会泄漏内存

例如:

很可能您不了解.NET的内存管理是如何工作的。NET使用一个垃圾收集器,它每隔一段时间只收集一次内存—除非泄漏的内存超过10-20个MiB,否则您可能不会遇到问题。有几件事情可能会在这里或那里生成一些对象,导致内存使用量有所增加,甚至游戏循环中的Application.DoEvents都是次优的。如果您正在进行实时渲染,那么不妨看看SharpDX/SlimDX之类的图形库。我查看了SlimDX,但因为我不需要什么密集型,只需要一些位图和一些文本,我想这就可以了。我想我会改成Dispatcher。调用就像PieterSchool和DJ KRAZE说的。好吧,Dispatcher。调用仍然有内存开销。换一种方式考虑—您真的希望以固定FPS进行实时渲染,还是希望使用基于事件的渲染?如果是实时的,保持循环不变,就可以了。如果基于事件,Winforms和WPF都能很好地工作,那么就不需要为了它而使用游戏循环。没错。。。起初我以为我需要实时,但现在。。。你说得对,我真的不需要它。感谢大家的帮助:我同意不要使用Application.DoEvents;这不是一个好的实践,你没有深入阅读它-这是一个明显的游戏循环,而不是在Winforms中尝试协作多任务。Application.DoEvents循环已经用于此用途一段时间了。它们不是制作游戏循环的最佳方式,但也不是那么糟糕。Application.DoEvents正在阻塞。当某件事情以某种方式做了很长时间后,这并不是一个好的选择。但是你错过了要点——调用根本帮不上什么忙。事实上,这是一个很好的方法,可以扼杀任何获得良好性能的机会——它将导致大量不必要的分配,并且OP很可能甚至没有任何控件可更新。我可能错了,但我认为他只是在用GDI+制作一个游戏——除非他将自定义渲染与实际的winforms/WPF控件结合起来,否则调用比无用还要糟糕。