Tôi có một ứng dụng CF mà theo thời gian rò rỉ UserControls. Phải mất một thời gian, nhưng tôi thu hẹp nó xuống, và thậm chí nhân rộng các hành vi trong khuôn khổ đầy đủ (3.5). Vì hành vi tồn tại trong cả hai, tôi không muốn gọi nó là lỗi, nhưng tôi chắc chắn không hiểu tại sao nó lại xảy ra và hy vọng ai đó có thể làm sáng tỏ nó.GC không hoàn thành UserControl?
Vì vậy, tôi tạo một ứng dụng WinForms đơn giản với Biểu mẫu và nút. Nhấp vào nút thay đổi giữa việc tạo UserControl mới và loại bỏ điều khiển đó. Rất đơn giản.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
UserControl1 m_ctl;
private void button1_Click(object sender, EventArgs e)
{
if (m_ctl == null)
{
m_ctl = new UserControl1();
m_ctl.Visible = true;
this.Controls.Add(m_ctl);
}
else
{
this.Controls.Remove(m_ctl);
m_ctl.Dispose();
m_ctl = null;
GC.Collect();
}
}
}
Và đây là UserControl. Nó chỉ đơn giản theo dõi số lượng các phiên bản trực tiếp (tức là chưa hoàn thành). Nó không có gì trên nó, nhưng một nhãn duy nhất để tôi có thể xác nhận trực quan nó trên Form.
public partial class UserControl1 : UserControl
{
private static int m_instanceCount = 0;
public UserControl1()
{
var c = Interlocked.Increment(ref m_instanceCount);
Debug.WriteLine("Instances: " + c.ToString());
InitializeComponent();
}
~UserControl1()
{
var c = Interlocked.Decrement(ref m_instanceCount);
Debug.WriteLine("Instances: " + c.ToString());
}
}
Điều kỳ lạ ở đây là số lượng cá thể phát triển vô thời hạn. Cuối cùng, trên thiết bị, tôi hết bộ nhớ. Tôi nghi ngờ tôi sẽ trên máy tính là tốt, tôi chỉ không có khuynh hướng nhấp vào nút cho năm tiếp theo.
Bây giờ nếu tôi thay đổi mặc định, phương thức Dispose nhà thiết kế tạo của UserControl như thế này, chỉ cần thêm các cuộc gọi ReRegisterForFinalize:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
if (disposing)
{
GC.ReRegisterForFinalize(this);
}
}
Sau đó, nó cư xử chính xác như mong đợi, Hoàn thiện các trường hợp trong bộ sưu tập (khi tay hoặc tự động) .
Vậy tại sao điều này lại xảy ra? Rõ ràng căn cứ đang gọi SuppressFinalize, nhưng chính xác tại sao điều này lại xảy ra, và tại sao trong cái tên Odin là hành vi mặc định?
+1 cho thực sự có một lý do thực sự để xem xét sử dụng GC, – Sayse
Xét Reed (xin lỗi không thể được giúp đỡ về các giải pháp thực tế!) câu trả lời, finalizer trong mã thực sự của bạn làm gì? Không thể gọi trình hoàn thành gây ra sự rò rỉ? – svick
Mã thực sự không có finalizers. Họ có Dispose đã được triển khai, và Bitmaps và những thứ tương tự đang được xử lý. – ctacke