2011-08-28 76 views
5

我正在开发一个BlackJack程序,该程序显示了一个BlackJack Table,卡片等等。计划是它将一个接一个地用一个自动化的策略连续播放数千手。C#WPF BitmapSource内存泄漏?

我有一个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()是我在另一个网站上找到的,它表示这是从Bitmap释放资源的最佳方式。这可能会有一个小的影响,但不是我在找什么。我也试过Dispose()。

另一个网站说它必须与ItemsSource绑定。我删除了绑定和内存仍然增长。相反,我离开了绑定并删除了生成位图的代码。它发挥了4万轮,并没有实质性增长(可能在运行40分钟时增加20MB)。

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

我该如何让这些图像显示在屏幕上,但也确保它们的物体在不再需要时被物体破坏?

谢谢你的时间。

回答

6

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

也就是说,从流创建BitmapSource对象时出现问题。当流被丢弃时,由流保存的byte[]不会被释放。 See my own question here。我没有投票结束复制的唯一原因是因为我认为你应该真的只创建一次卡片,并且完成它而不是创建这些图像10,000次以上。

+0

这是有道理的。如果我在应用程序启动时生成一个BitmapSource,我应该能够引用正确的?它只会在CardInHand类中存储对原始BitmapSource的引用,而不会复制数据,对吧? –

+0

51卡? 52? ... –

+0

.... Geez,是... 52. Point stands = D –