私は、ブラックジャックテーブル、カードなどを表示するブラックジャックプログラムを開発しています。それは、自動化された戦略で次々に何千もの手を演奏する予定です。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プロパティを無効にしてみましたが、無駄です。
これらの画像を画面に表示させることはできますが、不要になったオブジェクトは確実に破棄されますか?
ありがとうございます。
これは意味があります。アプリケーションの起動時にBitmapSourceを生成すると、それを正しく参照できるはずです。 CardInHandクラスにオリジナルのBitmapSourceへの参照を保存し、データを複製しないだけです。 –
51枚ですか? 52? ... –
....ちょっと、そう... 52.ポイントスタンド= D –