Производительность ReactiveUI ObservableAsPropertyHelper - PullRequest
0 голосов
/ 16 января 2020

Код:

public class AppViewModel : ReactiveObject
{
    public AppViewModel()
    {
        Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
        .Do(_ => Score++)
        .Subscribe();
    }

    private long _score;
    public long Score
    {
        get => _score;
        set => this.RaiseAndSetIfChanged(ref _score, value);
    }
}

Функционально эквивалентен:

public class AppViewModel : ReactiveObject
{
    private readonly ObservableAsPropertyHelper<long> _score;

    public AppViewModel()
    {
        _score =
            Observable
            .Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.Score);
    }

    public long Score => _score.Value;
}

Хотя, во втором случае, перед моей заметной задержкой (более секунды на моей машине) отсчет начинается. Что может быть причиной этого?

Для полноты:

MainWindow.xaml

<reactiveui:ReactiveWindow 
    x:Class="ReactiveDemo.MainWindow"
    x:TypeArguments="reactivedemo:AppViewModel"
    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"
    xmlns:reactivedemo="clr-namespace:ReactiveDemo"
    xmlns:reactiveui="http://reactiveui.net"
    Title="Rx" Height="450" Width="800"
    mc:Ignorable="d">
    <Viewbox>
        <Label x:Name="ScoreLabel" ContentStringFormat="D2" FontFamily="Lucida Console" />
    </Viewbox>
</reactiveui:ReactiveWindow>

MainWindow.xaml.cs

using ReactiveUI;
using System.Reactive.Disposables;

namespace ReactiveDemo
{
    public partial class MainWindow : ReactiveWindow<AppViewModel>
    {
        public MainWindow()
        {
            InitializeComponent();

            ViewModel = new AppViewModel();

            this.WhenActivated(disposableRegistration =>
            {
                this.OneWayBind(ViewModel,
                    viewModel => viewModel.Score,
                    view => view.ScoreLabel.Content)
                    .DisposeWith(disposableRegistration);
            });
        }
    }
}

1 Ответ

1 голос
/ 17 января 2020

Перегрузка ToProperty, которую вы используете, имеет стоимость отражения. Попробуйте ToProperty(this, nameof(Score)). Может все еще наблюдаться снижение производительности, так как ToProperty делает немного больше, чем функциональный эквивалент, который вы опубликовали.

...