我正在开发一个 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;
}
问题是,在我运行了大约 500 轮(大约 4000 手或大约 10000 张卡片)之后,我最终遇到了 GDI+ 错误,并且应用程序占用了大约 400MB 的 RAM。这增长很快,并且与已玩过的手数有关。
DeleteObject() 是我在另一个站点上发现的,它说这是从位图中释放资源的最佳方式。它可能会产生很小的影响,但不是我想要的。我也尝试过 Dispose()。
另一个网站说它与 ItemsSource 绑定有关。我去掉了绑定,记忆还在增长。相反,我离开了绑定并删除了生成位图的代码。它玩了 40,000 轮,并没有大幅增长(可能在运行 40 分钟后增加了 20MB)。
ObservableCollection 在每一轮之后都会被清除()。我尝试将集合、CardInHand 和 BitmapSource 属性归零,但无济于事。
如何让这些图像显示在屏幕上,同时确保它们的对象在不再需要后被正确销毁?
感谢您的时间。