如何异步执行WhenAnyValue委托?

时间:2017-07-14 17:27:34

标签: c# asynchronous reactiveui

我有这个代码每次另一个属性更改时生成“计算”或“输出”属性。派生属性是正确生成的,但由于CreateBlurImage有点长时间运行,因此UI在运行时会被冻结。

获得相同的最终结果的正确方法是什么,但是异步?

编辑这是我的代码的当前版本,经过@Shane的一些建议,但仍然保持冻结的UI,直到所有处理完成。请注意,如果重要的话,还有一些级联更新:

    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 个答案:

答案 0 :(得分:3)

这些方法中的任何一种都有效吗?这样CreateBlurImage部分就完成了UIThread

String

或者我非常确定在ToProperty上指定调度程序将与上面相同

public MyClass()
{
    this.WhenAnyValue(x => x.StripedImage)
        .ObserveOn(RxApp.TaskpoolScheduler)
        .Select(im => CreateBlurImage(im))
        .ObserveOn(RxApp.MainThreadScheduler)
        .ToProperty(this, x => x.Filtered, out _filtered);
}