2011-08-28 49 views
5

Tôi đang phát triển một chương trình BlackJack hiển thị Bảng BlackJack, thẻ, v.v. Kế hoạch là nó sẽ chơi hàng ngàn tay cái khác với chiến lược tự động.C# WPF BitmapSource Bộ nhớ Rò rỉ?

Tôi có một UserSeat UserControl có chứa một ItemsControl bị ràng buộc với một ObservableCollection. Lớp CardInHand này chứa một BitmapSource có tên là CardImage. Khi dụ được crated nó tải các hình ảnh thẻ từ nguồn sử dụng đoạn mã sau:

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

Vấn đề là sau khi tôi chạy qua ~ 500 viên đạn (~ 4000 tay hay ~ 10000 thẻ) Tôi kết thúc với một GDI + lỗi và ứng dụng chiếm ~ 400MB RAM. Điều này phát triển nhanh chóng và có liên quan đến số lượng bàn tay đã được chơi.

DeleteObject() là thứ tôi đã tìm thấy trên một trang web khác cho biết đây là cách tốt nhất để giải phóng tài nguyên từ Bitmap. Đó là MIGHT có một ảnh hưởng nhỏ, nhưng không phải những gì tôi đang tìm kiếm. Tôi cũng đã thử Dispose().

Một trang web khác cho biết nó phải làm với ràng buộc ItemsSource. Tôi loại bỏ các ràng buộc và bộ nhớ vẫn phát triển. Inversely tôi rời khỏi ràng buộc và loại bỏ các mã mà tạo ra các bitmap. Nó chơi 40.000 vòng và không phát triển đáng kể (có thể + 20MB trong 40 phút nó đang chạy).

ObservableCollection là Clear() ed sau mỗi vòng. Tôi đã thử nulling bộ sưu tập, CardInHand, và các bitmapSource propery, vô ích.

Làm cách nào để cho phép các hình ảnh này hiển thị trên màn hình mà còn đảm bảo rằng các đối tượng của chúng bị hủy hoàn toàn sau khi chúng không còn cần thiết nữa?

Cảm ơn bạn đã dành thời gian.

Trả lời

6

Vì vậy, trước hết, bạn chỉ có 52 thẻ. Chỉ cần tạo ra các hình ảnh lên phía trước và giữ chúng xung quanh cho cuộc sống của ứng dụng. Nó là một trò chơi Black Jack sau tất cả; nó là an toàn để giả định rằng mỗi thẻ sẽ được cần thiết tại một thời điểm này hay cách khác.

Điều đó nói rằng có sự cố khi tạo các đối tượng từ các đối tượng địa lý là BitmapSource. Các byte[] được tổ chức bởi các dòng không được giải phóng khi dòng được xử lý. See my own question here. Lý do duy nhất tôi không bỏ phiếu để đóng như là một bản sao là bởi vì tôi nghĩ rằng bạn thực sự chỉ cần tạo các thẻ một lần và được thực hiện với nó thay vì tạo ra những hình ảnh 10.000 lần.

+0

Điều này có ý nghĩa. Nếu tôi tạo BitmapSource khi khởi động ứng dụng, tôi có thể tham khảo chính xác? Nó sẽ chỉ lưu trữ một tham chiếu đến BitmapSource gốc trong lớp CardInHand, và không sao chép dữ liệu, đúng không? –

+0

51 thẻ? 52? ... –

+0

.... Geez, vâng ... 52. Điểm đứng = D –