C# WPF BitmapSource 内存泄漏? [英] C# WPF BitmapSource Memory Leak?

查看:256
本文介绍了C# WPF BitmapSource 内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个显示 21 点牌桌、纸牌等的 21 点游戏程序.计划是它会使用自动化策略接连玩上千手牌.

I'm developing a BlackJack program which shows a BlackJack Table, cards, etc. The plan is that it'll be playing thousands of hands one after another with an automated strategy.

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

I have a PlayerSeat UserControl which contains an ItemsControl bound to a ObservableCollection. This CardInHand class contains a BitmapSource named CardImage. When the instance is crated it loads the card image from resources using the following code:

[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;
}

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

The problem is that after I run through ~500 rounds (~4000 hands or ~10000 cards) I end up with a GDI+ error and the application taking up ~400MB of RAM. This grows quickly and is related to the number of hands that have been played.

DeleteObject() 是我在另一个站点上找到的东西,它说这是从位图中释放资源的最佳方式.它可能有一点影响,但不是我想要的.我也试过 Dispose().

DeleteObject() is something I had found on another site which said that this is the best way to release the resources from the Bitmap. It's MIGHT be having a small affect, but not what I'm looking for. I've also tried Dispose().

另一个站点说它与 ItemsSource 绑定有关.我删除了绑定,内存仍然增长.相反,我离开了绑定并删除了生成位图的代码.它播放了 40,000 轮并且没有显着增长(在它运行的 40 分钟内可能增加了 20MB).

Another site said it had to do with ItemsSource binding. I removed the binding and memory still grew. Inversely I left the binding and removed the code that generates the bitmap. It played 40,000 rounds and did not grow substantially (maybe +20MB over the 40min it was running).

ObservableCollection 在每一轮之后被清除().我试过将集合、CardInHand 和 BitmapSource 属性置空,但无济于事.

The ObservableCollection is Clear()ed after every round. I've tried nulling the collection, the CardInHand, and the BitmapSource propery, to no avail.

我怎样才能让这些图像显示在屏幕上,同时确保它们的对象在不再需要后被销毁?

How can I allow these images to display on the screen but also make sure their objects are propery destroyed after they're no longer needed?

感谢您的宝贵时间.

推荐答案

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

So first off, you only have 52 cards. Just create the images up front and keep them around for the life of the application. It is a Black Jack game after all; it is safe to assume that each card will be needed at one point or another.

也就是说,从流创建 BitmapSource 对象存在问题.当流被释放时,流持有的 byte[] 不会被释放.在这里查看我自己的问题.我没有投票关闭重复的唯一原因是因为我认为你真的应该只创建一次卡片并完成它,而不是创建这些图像 10,000 多次.

That said, there is an issue with creating BitmapSource objects from streams. The byte[] held by the stream is not being freed when the stream is disposed. See my own question here. The only reason I didn't vote to close as a duplicate is because I think you should really just create the cards once and be done with it instead of creating these images 10,000+ times.

这篇关于C# WPF BitmapSource 内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆