我有一个 Xamarin/Prism 应用程序(不是我的代码),它有各种事件订阅和许多内存泄漏。我认为内存泄漏之一与这些事件订阅有关。这是它们以前的样子:
public HomePage(IEventAggregator eventAggregator)
{
InitializeComponent();
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<MyEvent>().Subscribe(async(x) =>
{
await MyAction(x);
});
}
protected override void OnDisappearing()
{
_eventAggregator.GetEvent<MyEvent>().Unsubscribe(UnrelatedHandleMyEvent);
}
private void UnrelatedHandleMyEvent(MyParameters obj)
{
Debug.WriteLine(obj);
}
public HomePageViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<MyOtherEvent>().Subscribe(async (x) =>
{
await MyOtherAction(x);
});
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
_eventAggregator.GetEvent<MyOtherEvent>().Unsubscribe(UnrelatedHandleMyOtherEvent);
}
private void UnrelatedHandleMyOtherEvent(MyOtherParameters obj)
{
Debug.WriteLine("Unsubscribing from other Event");
}
我想用以下内容替换它们:
SubscriptionToken myEventToken;
public HomePage(IEventAggregator eventAggregator)
{
InitializeComponent();
_eventAggregator = eventAggregator;
}
protected override void OnAppearing()
{
myEventToken = _eventAggregator.GetEvent<MyEvent>().Subscribe(async(x) => { await MyAction(x); });
}
protected override void OnDisappearing()
{
myEventToken.Dispose()
}
SubscriptionToken myOtherEventToken;
public HomePageViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
}
public override void OnNavigatedTo(INavigationParameters parameters)
{
myOtherEventToken = _eventAggregator.GetEvent<MyOtherEvent>().Subscribe(async (x) => { await MyOtherAction(x); });
}
public override void OnNavigatedFrom(INavigationParameters parameters)
{
myOtherEventToken.Dispose();
}
我的两个主要更改是用现在保存的 SubscriptionToken 上的 Dispose 调用替换 Unsubscribe 调用,并将 Subscribe 调用移至相应的页面生命周期挂钩,而不是构造函数。我对取消订阅修复很有信心,我确信这是内存泄漏的主要原因,但是我不确定是否从构造函数转移到生命周期挂钩 - 我在网上看到的每个地方似乎都有它们在构造函数中,但是这个不适合我。生命周期钩子应该是对称的和一对一的 - 与构造函数相反。
我使用的是 Xamarin.Forms 4.8 和 Prism.DryIoc.Forms 7.2
我做得对吗?
在构造函数外部订阅没有问题,在导航到之前接收事件可能没有意义:-)
您需要查看
IApplicationLifecycleAware
和 IPageLifeCycleAware
,因为 OnNavigatedTo
和 OnNavigatedFrom
仅在实际导航时调用,而不是在例如导航时调用。关闭应用程序或按硬件后退按钮。
当应用程序进入后台并稍后被点击时,它可能会从头开始或只是恢复,因此请注意可能的双重订阅。