2011-08-28 124 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 –