Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 导航后未释放ViewModel实例_C#_Uwp_Prism - Fatal编程技术网

C# 导航后未释放ViewModel实例

C# 导航后未释放ViewModel实例,c#,uwp,prism,C#,Uwp,Prism,UWP应用程序(Prism.Unity NuGetPackage 6.3.0) 当多次导航到同一页时,将创建其视图模型的新实例,旧实例将保存在内存中,不会被释放 这会导致崩溃,因为全局事件会使用事件聚合器触发多次,而侦听它的旧ViewModels也会接收到全局事件聚合器 我们正在使用NavigationService浏览页面。我们的页面和用户控件绑定到带有XAML中的prismmvm:ViewModelLocator.AutoWireViewModel=“True”的viewmodels 我们已

UWP应用程序(Prism.Unity NuGetPackage 6.3.0)

当多次导航到同一页时,将创建其视图模型的新实例,旧实例将保存在内存中,不会被释放

这会导致崩溃,因为全局事件会使用事件聚合器触发多次,而侦听它的旧ViewModels也会接收到全局事件聚合器

我们正在使用NavigationService浏览页面。我们的页面和用户控件绑定到带有XAML中的
prismmvm:ViewModelLocator.AutoWireViewModel=“True”
的viewmodels

我们已经看到一些关于类似问题的线程,解决方案是使用区域添加区域行为。然而,据我所知,Prism UWP在其当前版本中不支持区域

我们认为问题与ViewModelLocator和NavigationService有关,因为向Container.RegisterType和其他LifetimeManager注册viewmodels没有效果

可以从GitHub下载崩溃示例:

复制:

  • 执行应用程序
  • 在Test1和Test2之间导航几次
  • 点击“RaiseEvent”执行全局事件
  • 所有实例都记录其哈希代码
  • 应用程序应该在某个时候崩溃
  • 这会导致崩溃,因为全局事件会使用事件聚合器触发多次,而侦听它的旧ViewModels也会接收到全局事件聚合器

    当您从一个页面导航到另一个页面时,可以取消订阅事件

    例如:

    public class Test1PageViewModel : ShellIntegratedViewModel
    {
        private readonly IEventAggregator _eventAggregator;
        private readonly INavigationService _navigationService;
        Action action;
        public Test1PageViewModel(IEventAggregator eventAggregator, INavigationService navigationService)
            : base(eventAggregator)
        {
            _eventAggregator = eventAggregator;
            _navigationService = navigationService;
    
            NavigateCommand = new DelegateCommand(OnNavigateCommand);
            action = new Action(()=> {
                _eventAggregator.GetEvent<LogEvent>().Publish("Test1 Hashcode: " + this.GetHashCode());
            });
            _eventAggregator.GetEvent<TestEvent>().Subscribe(action);
        }
        private void OnNavigateCommand()
        {
            _eventAggregator.GetEvent<TestEvent>().Unsubscribe(action);
            _navigationService.Navigate("Test2", null);
        }
    
        public DelegateCommand NavigateCommand { get; private set; }
    }
    
    公共类Test1PageViewModel:ShellIntegratedViewModel
    {
    私有只读ieventagegrator\u事件聚合器;
    私有只读INavigationService(导航服务);
    行动;
    公共测试1页面视图模型(IEventAggregator事件聚合器,iVigationService navigationService)
    :base(事件聚合器)
    {
    _eventAggregator=eventAggregator;
    _导航服务=导航服务;
    NavigateCommand=新的DelegateCommand(OnNavigateCommand);
    动作=新动作(()=>{
    _eventAggregator.GetEvent().Publish(“Test1 Hashcode:+this.GetHashCode());
    });
    _eventAggregator.GetEvent().Subscribe(操作);
    }
    私有void OnNavigateCommand()
    {
    _eventAggregator.GetEvent().取消订阅(操作);
    _navigationService.Navigate(“Test2”,null);
    }
    public DelegateCommand NavigateCommand{get;private set;}
    }
    
    除非您告诉订阅方,否则订阅不会使订阅方保持活动状态。