C#WPF BitmapSource内存泄漏?

Cae*_*lan 5 c# wpf memory-leaks bitmapsource

我正在开发一个BlackJack程序,它显示了BlackJack表,卡片等.计划是它将通过自动化策略一个接一个地玩数千手牌.

我有一个PlayerSeat UserControl,它包含一个绑定到ObservableCollection的ItemsControl.此CardInHand类包含名为CardImage的BitmapSource.当实例被装箱时,它使用以下代码从资源加载卡片图像:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

private BitmapSource GenerateCardImage() {
        Stream TempStream = this.GetType().Assembly.GetManifestResourceStream("BlackJack.Resources.CardImages.Card_" + m_Card.ShortTitle + ".gif");
        System.Drawing.Bitmap sourceBMP = new System.Drawing.Bitmap(TempStream);
        BitmapSource tempBitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
            sourceBMP.GetHbitmap(),
            IntPtr.Zero,
            System.Windows.Int32Rect.Empty,
            BitmapSizeOptions.FromWidthAndHeight(sourceBMP.Width, sourceBMP.Height)
        );
        TempStream.Dispose();
        DeleteObject(sourceBMP.GetHbitmap());
        return tempBitmapSource;
}
Run Code Online (Sandbox Code Playgroud)

问题是,在我运行~500轮(~4000手或~10000卡)后,我最终得到了GDI +错误,应用程序占用了大约400MB的RAM.这种增长很快,并且与已经玩过的手的数量有关.

DeleteObject()是我在另一个站点上发现的,它说这是从Bitmap释放资源的最佳方法.这可能会产生一些影响,但不是我正在寻找的东西.我也尝试过Dispose().

另一个网站表示它与ItemsSource绑定有关.我删除了绑定,内存仍然增长.反过来,我离开了绑定并删除了生成位图的代码.它打了4万发子弹并且没有大幅度增长(在运行的40分钟内可能+ 20MB).

每一轮后,ObservableCollection都是Clear().我已经尝试将集合,CardInHand和BitmapSource属性归零,但无济于事.

如何让这些图像显示在屏幕上,同时确保它们的对象在不再需要后会被破坏?

感谢您的时间.

Ed *_* S. 6

首先,你只有52张牌.只需预先创建图像并在应用程序的生命周期中保留它们.毕竟这是一个黑杰克游戏; 可以安全地假设每张卡都需要在某一点或另一点.

也就是说,BitmapSource从流创建对象存在问题.在byte[]由流保持的流被设置时,不被释放. 在这里看到我自己的问题.我没有投票以关闭作为副本的唯一原因是因为我认为你应该只创建一次卡片并完成它而不是创建这些图像10,000次以上.

  • [享元模式](http://en.wikipedia.org/wiki/Flyweight_pattern) 的经典示例在这里。 (2认同)