¿Por qué los controles de contenido de Silverlight no son basura recolectada?

He estado investigando por qué algunos de mis controles no se están recolectando basura y noté que es fácil evitar que los controles simples que heredan de ContentControl se destruyan. Aquí hay un ejemplo:

Aquí está mi ContentControl personalizado:

 public class MyCustomControl : ContentControl
{

    public MyCustomControl()
    {
        Debug.WriteLine("Constructed");
    }

    ~MyCustomControl()
    {
        Debug.WriteLine("Destroyed");
    }
}

Ahora si lo pongo en una página así:

<navigation:Page x:Class="SimpleTestBed.Views.CustomControl" 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       mc:Ignorable="d"
       xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
             xmlns:local="clr-namespace:SimpleTestBed"
       d:DesignWidth="640" d:DesignHeight="480"
       Title="CustomControl Page">
<Grid x:Name="LayoutRoot">

    <StackPanel>
        <local:MyCustomControl>
            <TextBox Text="{Binding SomeProperty,Mode=TwoWay}"></TextBox>
        </local:MyCustomControl>
    </StackPanel>

</Grid>

Con el siguiente código detrás:

 public partial class CustomControl : Page
{
    public CustomControl()
    {
        InitializeComponent();

        this.DataContext = new CustomControlViewModel();

        this.Unloaded += new RoutedEventHandler(OnUnloaded);
    }

    void OnUnloaded(object sender, RoutedEventArgs e)
    {
        this.DataContext = null;
    }

    // Executes when the user navigates to this page.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }



}

Entonces el modelo de vista es:

  public class CustomControlViewModel : INotifyPropertyChanged
{

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        RaisePropertyChanged(propertyName);
    }
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion


    private string _someProperty = "Initial Value";
    public string SomeProperty
    {
        get { return _someProperty; }
        set
        {
            if (_someProperty != value)
            {
                string oldValue = _someProperty;
                _someProperty = value;
                OnPropertyChanged("SomeProperty");
                OnSomePropertyChanged(oldValue, value);
            }
        }
    }



    protected virtual void OnSomePropertyChanged(string oldValue, string newValue)
    {

    }


}

Ahora, cuando navego fuera de esta página e intento recolectar basura con GC.Collect (), siempre que no haya realizado cambios en el texto en el Cuadro de texto, el Control de contenido y la Página se destruyen según lo esperado por el GC. Pero si he editado algo de texto y me he alejado de la página y luego he intentado GC.Collect (), ContentControl no obtiene la basura recolectada.

¿Alguien puede explicar este comportamiento?

En realidad, puede forzar al GC a recopilar el control 'parpadeando' la plantilla del control cuando descargue:

  void MyCustomControl_Unloaded(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("MyCustomControl Unloaded");
        ControlTemplate oldTemplate = this.Template;
        this.Template = null;
        this.Template = oldTemplate;
    }

Supongo que esto destruye el árbol visual actual perdiendo referencias del primer componente del árbol a su padre (el control personalizado). Ciertamente obliga al control a recuperar OnApplyTemplate cuando el control se vuelve a cargar.

¿Es este el patrón correcto para desarrollar controles de Silverlight sin fugas? Si es así, me parece un poco extraño que la plantilla no se elimine automáticamente cuando se descarga el control.

Una buena explicación de este comportamiento sería muy apreciada ya que va directamente al corazón del ciclo de vida de los controles de Silverlight.

Respuestas a la pregunta(1)

Su respuesta a la pregunta