C# ReactiveUI单向绑定泄漏句柄

C# ReactiveUI单向绑定泄漏句柄,c#,idisposable,reactiveui,C#,Idisposable,Reactiveui,我有一个简单的ViewModel: public class MeetingPageViewModel : ReactiveObject, IRoutableViewModel { public MeetingPageViewModel(IScreen hs, IMeetingRef mRef) { HostScreen = hs; _backing = "hi there"; } public IScreen HostScree

我有一个简单的ViewModel:

public class MeetingPageViewModel : ReactiveObject, IRoutableViewModel
{
    public MeetingPageViewModel(IScreen hs, IMeetingRef mRef)
    {
        HostScreen = hs;
        _backing = "hi there";
    }

    public IScreen HostScreen { get; private set; }

    public string MeetingTitle
    {
        get { return _backing; }
        set { this.RaiseAndSetIfChanged(ref _backing, value); }
    }
    string _backing;

    public string UrlPathSegment
    {
        get { return "/meeting"; }
    }
}
我将会议标题绑定到一个文本块:

public sealed partial class MeetingPage : Page, IViewFor<MeetingPageViewModel>
{
    public MeetingPage()
    {
        this.InitializeComponent();

        // Bind everything together we need.
        this.OneWayBind(ViewModel, x => x.MeetingTitle, y => y.MeetingTitle.Text);
    }

    /// <summary>
    /// Stash the view model
    /// </summary>
    public MeetingPageViewModel ViewModel
    {
        get { return (MeetingPageViewModel)GetValue(ViewModelProperty); }
        set { SetValue(ViewModelProperty, value); }
    }
    public static readonly DependencyProperty ViewModelProperty =
        DependencyProperty.Register("ViewModel", typeof(MeetingPageViewModel), typeof(MeetingPage), new PropertyMetadata(null));

    object IViewFor.ViewModel
    {
        get { return ViewModel; }
        set { ViewModel = (MeetingPageViewModel)value; }
    }
}
public sealed分部类会议第页:第页,IViewFor
{
公众会议网页()
{
this.InitializeComponent();
//把我们需要的东西都绑在一起。
这个.OneWayBind(ViewModel,x=>x.MeetingTitle,y=>y.MeetingTitle.Text);
}
/// 
///隐藏视图模型
/// 
公开会议页面视图模型视图模型
{
获取{return(MeetingPageViewModel)GetValue(ViewModelProperty);}
set{SetValue(ViewModelProperty,value);}
}
公共静态只读从属属性ViewModelProperty=
DependencyProperty.Register(“ViewModel”、typeof(MeetingPageViewModel)、typeof(MeetingPage)、new PropertyMetadata(null));
对象IViewFor.ViewModel
{
获取{return ViewModel;}
设置{ViewModel=(MeetingPageViewModel)值;}
}
}

导航回上一次屏幕会议后,PageViewModel不会被垃圾收集。我正在使用RxUI和VS2013的6.4.1(以及内存分析工具)。如果我处理了OneWayBind的返回值,那么一切都会被正确地清理掉——当然,我不再有绑定。

事实证明问题在于DependencyProperty ViewModel。它的生命周期是永久的(注意声明中的“静态”)。因此,附加到它的绑定永远不会被垃圾收集,因为它永远不会消失,然后该绑定同时持有对视图和视图模型的引用,因此它们永远不会消失

打破这种状况的唯一方法是显式清理绑定。RxUI提供了WhenActivated方法来帮助实现这一点。将绑定包围在lambda中,并使用提供的函数跟踪IDisPoals。当视图消失时,将对其进行清理

this.WhenActivated(disposeOfMe => {
    disposeOfMe (this.OneWayBind(ViewModel, x => x.MeetingTitle, y => y.MeetingTitle.Text));
});

“离开”的确切含义是什么?当反应式系统处理视图时。它什么时候处理视图?(我应该去github并开始深入研究以回答我的问题吗?)你可能会。当我这样做的时候,我在处理时设置了一个断点,我似乎记得它是在上层的navagation调用期间。但更具体的说,恐怕这是很久以前的事了。此外,工具包已经进化,因此可能会有所不同。我正在阅读一本关于ReactiveUI的书,它建议在WPF中,在各种情况下清除它,包括从可视化树中删除视图时,并且可以通过注册自己的IActivationForViewFetcher来定制行为。听起来,reactiveUI确实相当明智。