c# WPF BitmapSource内存泄漏

本文关键字:泄漏 内存 BitmapSource WPF | 更新日期: 2023-09-27 18:06:54

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

我有一个PlayerSeat UserControl,它包含一个ItemsControl绑定到一个ObservableCollection。这个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;
}

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

DeleteObject()是我在另一个网站上发现的东西,该网站说这是从位图释放资源的最佳方式。这可能会有一点影响,但不是我想要的。我也试过Dispose()。

另一个网站说它与ItemsSource绑定有关。我移除了束缚,记忆依然在增长。相反,我留下了绑定并删除了生成位图的代码。它玩了40000回合,并没有大幅增长(在40分钟内可能增加了20MB)。

ObservableCollection在每轮结束后被Clear()清除。我已经尝试了null集合,CardInHand和BitmapSource属性,但无济于事。

我怎么能让这些图像显示在屏幕上,但也要确保他们的对象销毁后,他们不再需要?

感谢您的宝贵时间。

c# WPF BitmapSource内存泄漏

首先,你只有52张牌。只需预先创建图像,并在应用程序的整个生命周期中保留它们。毕竟这是一款"黑杰克"游戏;可以放心地假设,每一张卡都将在某个时刻被需要。

也就是说,从流中创建BitmapSource对象存在一个问题。当流被处理时,流持有的byte[]没有被释放。看看我自己的问题。我没有投票赞成复制的唯一原因是,我认为你应该只创建一次卡片,而不是创建10,000多次这些图像。