2011-08-28 17 views
5

BlackJack Tablo, kartlar vb. Gösteren bir BlackJack programı geliştiriyorum. Plan, otomatik bir strateji ile birbiri ardına binlerce eli oynayacak olmasıdır.C# WPF BitmapSource Bellek Sızıntısı?

ObservableCollection öğesine bağlı ItemsControl içeren bir PlayerSeat UserControl var. Bu CardInHand sınıfı, CardImage adında bir BitmapSource içerir. örnek crated edildiğinde aşağıdaki kodu kullanarak kaynaklardan kart resmi yükleyen:

[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; 
} 

sorun olduğunu ben ~ 500 mermi (~ 4000 eller veya ~ 10000 kartları) bir GDI ile sona aracılığıyla çalıştırdıktan sonra + hata ve uygulama yaklaşık 400MB RAM alıyor. Bu hızlı büyür ve çalınan el sayısı ile ilgilidir.

DeleteObject(), başka bir sitede bulduğum bir kaynaktır; bu, bunun kaynakları Bitmap'ten serbest bırakmanın en iyi yolu olduğunu söylemiştir. MIGHT'ın küçük bir etkisi var, ama aradığım şey değil. Ayrıca Dispose() çalıştım.

Başka bir site, bunun ItemsSource ciltlemesi ile ilgili olduğunu söyledi. Bağlamayı kaldırdım ve bellek hala büyüdü. Tersine, bağlayıcıyı bıraktım ve bitmap'i oluşturan kodu kaldırdım. Bu 40.000 mermi oynadı ve önemli ölçüde büyümedi (belki de 40km üzerinde koşuyordu).

ObservableCollection, her turdan sonra Clear() biçimindedir. Koleksiyon, CardInHand ve BitmapSource ürün grubunu boşa çıkarmayı denedim.

Bu görüntülerin ekranda görüntülenmesine nasıl izin verebilirim, ayrıca nesnelerin artık ihtiyaç duyulmadıktan sonra imha edilmesini nasıl sağlayabilirim?

Zaman ayırdığınız için teşekkür ederiz.

cevap

6

İlk olarak, yalnızca 52 kartınız var. Sadece ön taraftaki görüntüleri oluşturun ve uygulamanın ömrü boyunca onları saklayın. Sonuçta bir Black Jack oyunu; Her kartın bir noktada veya başka bir anda gerekli olacağını varsaymak güvenlidir.

Bu, akışlardan BitmapSource nesnesi oluşturma ile ilgili bir sorun olduğunu söyledi. Akış tarafından tutulan byte[] akışı, akım bertaraf edildiğinde serbest bırakılmaz. See my own question here. Çoğaltmak için oy vermememin tek nedeni, bu görüntüleri 10,000+ kez oluşturmak yerine gerçekten sadece bir kez kartları oluşturup onunla işin bitmesi gerektiğini düşünüyorum.

+0

Bu mantıklıdır. Uygulama başlangıcında bir BitmapSource oluşturursam, yalnızca bu düzeltmeye başvurabilir miyim? Sadece CardInHand sınıfındaki orijinal BitmapSource'a bir referans kaydeder ve verileri çoğaltmaz, değil mi? –

+0

51 kartlar? 52? ... –

+0

.... Geez, evet ... 52. Nokta standları = D –