How to execute WhenAnyValue delegate asynchronously?

Viewed 364

I have this code generating a "Calculated" or "Output" property every time another property changes. The derived property is generated correctly, but since CreateBlurImage is a bit long-running, the UI gets frozen as it runs.

What would be the correct way to get the same end result, but asynchronously?

EDIT this is the current version of my code after some suggestions from @Shane, but still with an UI that keeps frozen until all the processing completes. Notice that there are quite a handful of cascading updates, if that matters:

    public ColetaIsis Model { get; private set; }

    public string NomePaciente { get { return Model?.NomePaciente; } }
    public DateTime DataRealização { get { return Model.DataRealização; } }



    public BitmapSource Listras
    {
        get { return _listras; }
        set { this.RaiseAndSetIfChanged(ref _listras, value); }
    }
    BitmapSource _listras;


    public double[,] Grayscale { get { return _grayscale.Value; } }
    readonly ObservableAsPropertyHelper<double[,]> _grayscale;

    public double[,] BlurMenor { get { return _blurMenor.Value; } }
    readonly ObservableAsPropertyHelper<double[,]> _blurMenor;

    public double[,] BlurMaior { get { return _blurMaior.Value; } }
    readonly ObservableAsPropertyHelper<double[,]> _blurMaior;

    public double[,] Diferença { get { return _diferença.Value; } }
    readonly ObservableAsPropertyHelper<double[,]> _diferença;


    public BitmapSource FiltradaMenor { get { return _filtradaMenor?.Value; } }
    readonly ObservableAsPropertyHelper<BitmapSource> _filtradaMenor;

    public BitmapSource FiltradaMaior { get { return _filtradaMaior?.Value; } }
    readonly ObservableAsPropertyHelper<BitmapSource> _filtradaMaior;

    public BitmapSource ImagemDiferença { get { return _imagemDiferença?.Value; } }
    readonly ObservableAsPropertyHelper<BitmapSource> _imagemDiferença;


    public IEnumerable<ScatterPoint> Picos => _picos;
    IEnumerable<ScatterPoint> _picos;








    // CONSTRUTOR
    public ColetaIsisViewModel(ColetaIsis model) 
    {
        this.WhenAnyValue(x => x.Listras)
            .Where(item => item != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(im => GetArray.FromChannels(im, 0, 1))
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.Grayscale, out _grayscale, scheduler:RxApp.MainThreadScheduler);

        this.WhenAnyValue(x => x.Grayscale)
            .Where(item => item != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(ar => Gaussian.GaussianConvolution(ar, 1.5))
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.BlurMenor, out _blurMenor, scheduler: RxApp.MainThreadScheduler);

        this.WhenAnyValue(x => x.BlurMenor)
            .Where(item => item != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(ar => Gaussian.VerticalGaussianConvolution(ar, 5))
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.BlurMaior, out _blurMaior, scheduler: RxApp.MainThreadScheduler);

        this.WhenAnyValue(x => x.BlurMenor, x => x.BlurMaior)
            .Where(tuple => tuple.Item1 != null && tuple.Item2 != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(tuple => ArrayOperations.Diferença(tuple.Item1, tuple.Item2))
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.Diferença, out _diferença, scheduler: RxApp.MainThreadScheduler);



        this.WhenAnyValue(x => x.BlurMenor)
            .Where(item => item != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.FiltradaMenor, out _filtradaMenor, scheduler: RxApp.MainThreadScheduler);

        this.WhenAnyValue(x => x.BlurMaior)
            .Where(item => item != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.FiltradaMaior, out _filtradaMaior, scheduler: RxApp.MainThreadScheduler);

        this.WhenAnyValue(x => x.Diferença)
            .Where(item => item != null)
            .ObserveOn(RxApp.TaskpoolScheduler)
            .Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
            //.ObserveOn(RxApp.MainThreadScheduler)
            .ToProperty(this, x => x.ImagemDiferença, out _imagemDiferença, scheduler: RxApp.MainThreadScheduler);


        Model = model;

        Listras = Model.Listras;  // fires up the initial cascading updates
    }
1 Answers
Related