5

Bir Silverlight denetiminde birkaç Blend davranışı ve tetikleyici kullanıyorum. Otomatik olarak ayırma veya kontrolün artık kullanılmadığında (ör. Görsel ağaçtan kaldırıldığında) bir davranış veya tetikleme için OnDetaching() çağrıldığından emin olmak için herhangi bir mekanizma olup olmadığını merak ediyorum.Silverlight Davranışları için OnDetaching() otomatik çağırma

Benim sorunum, davranışlardan biri nedeniyle, denetim ile yönetilen bir bellek sızıntısı olmasıdır. Davranış, OnAttached() öğesindeki bazı uzun ömürlü nesnelerdeki bir olaya abone olur ve OnDetaching() uygulamasındaki aboneliği iptal eder ve böylece çöp toplama için aday olabilir. Ancak, Visual Tree'den kontrolü kaldırdığımda OnDetaching() asla çağrılmayacak gibi görünüyor ... ben bunu elde etmek için tek yol kontrol kaldırmadan ÖNCE sorunlu davranışları açıkça ayırmak ve sonra düzgün toplanan çöp olduğunu .

Şu anda tek çözümüm, denetim için kodun arkasında, çöp toplama sorunlarına yol açabilecek bilinen davranışları çözebilen ve ayırabilen bir genel yöntem oluşturmaktı. Denetimin panelden kaldırılmasından önce bunu çağırmayı bilmek istemci koduna kalmış olur. Bu yaklaşımı gerçekten beğenmedim, bu yüzden bunu yaptığım veya daha iyi bir öneride bulunmanın otomatik bir yolunu arıyorum. Eğer gerçekten bu durumda gerekenler

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

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

cevap

3

otomatik uzun ömürlü nesne tarafından tutulan referans davranışını tutmaz (ve başka dolayısıyla her şeyin bir başvuru için vardır) dan emin olmak için ama ayırmak için bazı yol değildir çöp toplanmak.

Bu, bir Mediator kalıbı uygulayarak algılanmıştır. Kavram, uzun ömürlü nesneyi Behaviour ürününüze referansla bir delege vermemenizdir, bunun yerine bir Arabulucu sınıfı bir ara-alan olarak yaratırsınız. Arabulucu, uzun ömürlü nesneler olayına ekler ve davranışa bir WeakReference tutar. Uzun ömürlü nesne olayı tetiklediğinde, aracı, WeakReference'un hala canlı olduğunu kontrol eder, eğer varsa, olayı iletmek için bir yöntem çağırır. Olay gerçekleştiğinde, arabulucu WeakReference'un artık canlı olmadığını algılarsa, olay işleyicisini uzun ömürlü nesneden ayırır. Bu nedenle, davranışı durduran hiçbir şey yoktur ve toplanan çöplerin toplanmasıyla ilgili diğer her şey, geriye kalan tüm nesneler, hala uzun ömürlü nesneye bağlı ölü bir referansla çok küçük bir arabulucu örneğidir. Bu arabulucular küçük olduklarından gerçek bir problemi temsil etmiyorlar ve hatta olay bir sonraki seferde ortadan kalkacak.

Neyse ki, bu şeyi başkalarının zaten yapmış olduğu şeyleri yapmak zorunda değilsiniz. Bu WeakEventListener denir. Bu blog: Highlighting a "weak" contribution; Enhancements make preventing memory leaks with WeakEventListener even easier! konuyla ilgili mükemmel bir bağlantı setine sahiptir.

3

Joost van Schaik, bellek sızıntısı sorununu önlerken ekli davranışlardan gelen referansları temizlemenin alternatif bir yolunu sunar. AssociatedObject'in Loaded and Unloaded olaylarının delegelerini kullanarak temizleme çalışmasına bağlı.

Ayrıca ekli davranışlar için saplama oluşturmak için bir kod snippet'i sunar.

+0

Teşekkürler! Bu yaklaşım ihtiyaçlarımız için iyi çalıştı. – Jaans