5

Tôi đang sử dụng một số hành vi Blend và trình kích hoạt trên điều khiển đèn bạc. Tôi tự hỏi nếu có bất kỳ cơ chế tự động tách hoặc đảm bảo rằng OnDetaching() được gọi cho một hành vi hoặc kích hoạt khi kiểm soát không còn được sử dụng (tức là loại bỏ khỏi cây thị giác).Tự động gọi OnDetaching() cho Hành vi Silverlight

Vấn đề của tôi là có một rò rỉ bộ nhớ được quản lý với sự kiểm soát vì một trong những hành vi. Hành vi này đăng ký một sự kiện trên một số đối tượng tồn tại lâu dài trong ghi đè OnAttached() và nên hủy đăng ký khỏi sự kiện đó trong ghi đè OnDetaching() để nó có thể trở thành một ứng cử viên cho việc thu thập rác. Tuy nhiên, OnDetaching() dường như không bao giờ được gọi khi tôi loại bỏ điều khiển khỏi cây thị giác ... cách duy nhất tôi có thể làm cho nó xảy ra là bằng cách loại bỏ một cách rõ ràng các hành vi có vấn đề TRƯỚC KHI tháo kiểm soát và sau đó nó được thu gom đúng cách .

Ngay bây giờ giải pháp duy nhất của tôi là tạo ra một phương pháp nào trong code-behind cho sự kiểm soát có thể đi qua và tách bất kỳ hành vi nổi tiếng có thể gây ra vấn đề thu gom rác thải. Nó sẽ được vào mã khách hàng để biết để gọi này trước khi loại bỏ sự kiểm soát từ bảng điều khiển. Tôi không thực sự thích cách tiếp cận này, vì vậy tôi đang tìm một số cách tự động để làm điều này mà tôi đang xem hoặc một gợi ý tốt hơn.

public void DetachBehaviors() 
{ 
    foreach (var behavior in Interaction.GetBehaviors(this.LayoutRoot)) 
    { 
      behavior.Detach(); 
    } 

    //continue detaching all known problematic behaviors on the control.... 
} 

Trả lời

3

Điều bạn thực sự cần trong trường hợp này không phải là một cách để tự động tách nhưng để đảm bảo rằng tham chiếu do đối tượng tồn tại lâu dài không giữ hành vi (và do đó mọi thứ khác có liên quan đến) từ là rác được thu thập.

Điều này được thực hiện bằng cách triển khai mẫu Dàn xếp. Khái niệm là bạn không cung cấp cho đối tượng tồn tại lâu dài một đại biểu có tham chiếu đến Behaviour của bạn, thay vào đó bạn tạo một lớp hòa giải làm trung gian. Người hòa giải gắn với sự kiện đối tượng tồn tại lâu dài và giữ WeakReference đối với hành vi. Khi đối tượng tồn tại lâu dài kích hoạt sự kiện, người hòa giải kiểm tra rằng WeakReference vẫn còn hoạt động, nếu như vậy gọi một phương thức trên nó để truyền sự kiện. Nếu khi sự kiện xảy ra, người hòa giải thấy rằng WeakReference không còn hoạt động nữa, nó sẽ gỡ bộ xử lý sự kiện của nó khỏi đối tượng sống lâu.

Do đó không có gì ngăn cản hành vi và mọi thứ khác liên quan đến việc thu gom rác thải còn lại là một ví dụ hòa giải rất nhỏ với tham chiếu chết vẫn gắn liền với đối tượng tồn tại lâu dài. Vì những người trung gian này rất nhỏ nên họ không đại diện cho một vấn đề thực sự và ngay cả những vấn đề đó sẽ biến mất trong lần tiếp theo sự kiện xảy ra.

May mắn thay, bạn không phải tự mình xây dựng nội dung này cho những người khác đã thực hiện. Nó được gọi là WeakEventListener. Blog này: Highlighting a "weak" contribution; Enhancements make preventing memory leaks with WeakEventListener even easier! có một bộ liên kết tuyệt vời về chủ đề này.

3

Joost van Schaik cung cấp một cách khác để dọn dẹp tài liệu tham khảo từ các hành vi gắn liền, trong khi tránh các vấn đề với các rò rỉ bộ nhớ. Nó phụ thuộc vào việc thực hiện công việc dọn dẹp bằng cách sử dụng các delegate của các sự kiện Loaded và Unloaded của AssociatedObject.

Anh ấy cũng cung cấp một đoạn mã để tạo sơ khai cho các hành vi được đính kèm.

+0

Cảm ơn! Cách tiếp cận này hoạt động tốt cho nhu cầu của chúng tôi. – Jaans

Các vấn đề liên quan