2011-08-28 44 views
5

私は、ブラックジャックテーブル、カードなどを表示するブラックジャックプログラムを開発しています。それは、自動化された戦略で次々に何千もの手を演奏する予定です。C#WPF BitmapSourceメモリリーク?

ObservableCollectionにバインドされたItemsControlを含むPlayerSeat UserControlがあります。このCardInHandクラスには、CardImageという名前のBitmapSourceが含まれています。インスタンスがcratedされた場合には、次のコードを使用してリソースからカードの画像をロードします。

[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()も試みました。

もう1つのサイトは、ItemsSourceバインドと関係があると言いました。私は束縛を取り除き、記憶はまだ成長しました。逆に私はバインディングを残して、ビットマップを生成するコードを削除しました。それは40,000ラウンドを果たし、実質的に成長しなかった(それは、実行中の40分を超えると20MBを超えるかもしれない)。

ObservableCollectionはすべてのラウンド後にクリア()されます。私は、コレクション、CardInHand、およびBitmapSourceプロパティを無効にしてみましたが、無駄です。

これらの画像を画面に表示させることはできますが、不要になったオブジェクトは確実に破棄されますか?

ありがとうございます。

答えて

6

まず、52枚のカードしか持っていません。画像を前面に作成し、アプリケーションの寿命の間、それらを保持してください。それは結局ブラックジャックゲームです。各カードがある時点で必要になると想定するのは安全です。

つまり、ストリームからオブジェクトBitmapSourceを作成することに問題があります。ストリームが保持しているbyte[]は、ストリームが廃棄されても解放されません。 See my own question here。私が重複として閉じることに投票しなかった唯一の理由は、実際にカードを一度作成し、10,000回以上の画像を作成するのではなく、そのカードを使用して完了させるべきだと思うからです。

+0

これは意味があります。アプリケーションの起動時にBitmapSourceを生成すると、それを正しく参照できるはずです。 CardInHandクラスにオリジナルのBitmapSourceへの参照を保存し、データを複製しないだけです。 –

+0

51枚ですか? 52? ... –

+0

....ちょっと、そう... 52.ポイントスタンド= D –