【发布时间】:2020-05-10 05:55:36
【问题描述】:
嗨,
大约 6 个月前,我开始使用响应式 UI 并用它构建简单的应用程序
就在四个月前,我开始构建一个监控低级别网络的应用程序
所以,我用 C++ 实现网络部分,然后用 C# 构建 UI、数据库模型和逻辑
然后创建一个中间库来编组这个低级 API,
如您所知,此 API 将提供大量数据包。
因此,在 C# 中,我决定使用响应式 UI 和响应式编程来处理这些数据流
Rx 完美运行,使用这个高性能反应系统为我节省了几天的工作时间
但现在我有一个大问题:
当我浏览应用程序时,解析视图/视图模型的初始时间
太多了,平均约为1200-506 ms,这会导致问题,因为这会使应用看起来像冻结了
所以我尝试解决这个问题,或者解决它但没有任何帮助,
我跟踪了响应式 UI 的大部分/所有指南,但似乎没有任何效果
另外,请注意描述的奇怪行为
in this StackOverflow question: WhenActivated is called twice: 并尝试该解决方案,但不起作用。
所以我尝试实现我的自定义SimpleViewModelViewHost
SimpleViewModelViewHost.xaml
<UserControl x:Class="Sample.EnhancedViewModelViewHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="450" d:DesignWidth="800">
<ContentPresenter
x:Name="MainContent"
Content="{Binding Path=View}"
/>
</UserControl>
SimpleViewModelViewHost.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ReactiveUI;
namespace Sample
{
// https://stackoverflow.com/questions/36433709/whenactivated-is-called-twice-when-used-in-views-and-viewmodels-hosted-in-viewmo/36813328#36813328
/// <summary>
/// Interaction logic for EnhancedViewModelViewHost.xaml
/// </summary>
public partial class EnhancedViewModelViewHost : UserControl
{
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(
"ViewModel", typeof(object), typeof(EnhancedViewModelViewHost), new PropertyMetadata(default(object)));
public object ViewModel
{
get => GetValue(ViewModelProperty);
set
{
SetValue(ViewModelProperty, value);
if (value == null) { return; }
var view = ViewLocator.Current.ResolveView(value);
if (view != null)
{
View = view;
View.ViewModel = value;
}
else
{
MainContent.Content = value;
}
}
}
public static readonly DependencyProperty ViewProperty = DependencyProperty.Register(
"View", typeof(IViewFor), typeof(EnhancedViewModelViewHost), new PropertyMetadata(default(IViewFor)));
public IViewFor View
{
get => (IViewFor)GetValue(ViewProperty);
set => SetValue(ViewProperty, value);
}
public EnhancedViewModelViewHost()
{
DataContext = this;
InitializeComponent();
}
}
}
我知道这泄露了很多功能disposing of old view/viewModel .....
但现在性能很好:现在只需要大约250-300 ms,但仍然一点都不好
因为人眼可以注意到这种延迟
所以现在我遇到了一个大问题,所以我在 ReactiveUI 中用空视图创建了另一个简单的应用程序
没有绑定
猜猜看:问题仍然存在
我使用 Visual Studio 分析器跟踪start of a constructor of ViewModel 之间的时间
和WhenActivated in the View的结尾
所以我的问题是:反应式团队是否意识到了这个问题,或者只是我做错了什么,如果是,解决方案是什么
另请注意:
我尝试通过Creating 提高复杂布局中的性能并实现一个名为IHotReloadViewModel 的接口并实现一些逻辑来重用当前的ViewModel 而不是替换它
并获得性能from about 1350 ms -> 10 ms
片段
ViewModel 的一部分
public class ManageProjectsViewModel : ReactiveObject, IActivatableViewModel
{
// .....
[Reactive] public EditProjectViewModel SelectedProject { get; set; }
//.....
private AppDbManager AppDbManager { get; set; }
#region Commands
public ReactiveCommand<Unit, Unit> EditProject { get; set; }
public ReactiveCommand<Unit, Unit> CreateNewProject { get; set; }
public ReactiveCommand<Unit, Unit> DeleteProject { get; set; }
// ....
#endregion
private IDisposable LastProjectTrack { get; set; }
private Subject<Unit> FreeSelectedProject { get; set; }
public ManageProjectsViewModel()
{
Activator = new ViewModelActivator();
AppDbManager = Locator.Current.GetService<AppDbManager>();
#region Commands
var canOperateOnProject = this.WhenValueChanged(vm => vm.SelectedProjectLookup).Select(p => p != null);
EditProject = ReactiveCommand.Create(EditProjectImpl, canOperateOnProject);
CreateNewProject = ReactiveCommand.Create(CreateNewProjectImpl);
DeleteProject = ReactiveCommand.Create(DeleteProjectImpl, canOperateOnProject);
#endregion
FreeSelectedProject = new Subject<Unit>();
this.WhenActivated(disposables =>
{
ProjectAddedNotify.ObserveOnDispatcher().Subscribe(ProjectAddedNotifyImpl).DisposeWith(disposables);
FreeSelectedProject.ObserveOnDispatcher().Subscribe(FreeSelectedProjectImpl).DisposeWith(disposables);
});
}
// ...........
View.xaml.cs 的一部分
public partial class ManageProjectsView : ReactiveUserControl<ManageProjectsViewModel>
{
private bool called = false;
public ManageProjectsView()
{
InitializeComponent();
IDisposable mainDisposable = null;
mainDisposable = this.WhenActivated(disposable =>
{
// ........
this.BindCommand(ViewModel, vm => vm.CreateNewProject, v => v.NewProject).DisposeWith(disposable);
this.BindCommand(ViewModel, vm => vm.EditProject, v => v.EditProject).DisposeWith(disposable);
this.BindCommand(ViewModel, vm => vm.DeleteProject, v => v.DeleteProject).DisposeWith(disposable);
this.Bind(ViewModel, vm => vm.SelectedProject, v => v.SelectedProject.ViewModel).DisposeWith(disposable);
ProjectLookups.Events().SelectionChanged.Subscribe(args =>
{
if (args.AddedItems.Count > 0)
{
ViewModel.SelectedProjectLookup = (NPProjectLookup)args.AddedItems[0];
}
}).DisposeWith(disposable);
ProjectLookups.ApplyHorizontalScrolling();
ProjectLookups.AllowZoom();
mainDisposable.DisposeWith(disposable);
}, this); // either use this or not: performance issue exists
}
}
大多数视图/视图模型使用相同的结构
那么为什么我认为这是一个问题
因为我使用 ViewModel-View Locator 的简单实现测试了相同的 UI,并且一切都立即运行
还使用 Prism 和 DryIoC i work with it for a long time 对其进行了测试,一切都立即生效
那么知道是否有任何解决方案,或者我需要在当前的响应式 UI 应用程序中使用棱镜?
通知
- 首先我没有在 Github 的响应式 UI 问题中发布此问题:因为我不想让问题面板溢出可能不必要的问题,所以我需要在这里确定其他用户设备上是否存在此问题,如果我会报告它给响应式 UI 团队
更新 (1)
在测试了多个应用程序5 apps 后,我发现
- 调用WhenActivated Twice的问题与reactiveUI有关
- 性能问题
Delay of view仅在使用带有HandyControl UI 库的ReactiveUI 时发生,我仍然无法确定问题的根源,但因为它仅在使用HC和RI时发生,我决定创建This Issue at HandyControl in GitHub
更新(2)
【问题讨论】:
-
为什么用 (-) 关闭?这里发生了什么:说不能生产,我在两个库上提供了两个问题,并将完整的源代码链接到这些库存储库的问题,并带有一个完整的项目来重现问题?另外,如果管理员看到这个:@DPVreony 的回答在这里消失了两天,我现在才来发现它又出现了??所以我在这些问题上说这条评论被删除了!
标签: wpf reactiveui viewmodellocator