Deboucing 异步 属性 刷新

Deboucing async property refresh

非常感谢您对以下问题的帮助: A 在我的 class 中有一个 属性 让我们说

string Foo {get;set;}

class中有刷新功能。里面有一个很长的 运行 方法可以更新

Foo = await Task.Run()... etc. 

每秒调用 1000 次刷新时,如何避免 Task-s 堆叠?去抖动?节流?怎么做?项目中有Rx,我用的是dotnet core 2.2.

Class构造函数


    res = Observable.FromAsync(() => Task.Run(async () =>
    {
                       await Task.Delay(5000);
                       return "Example";
    }
    )).Throttle(TimeSpan.FromSeconds(10));

Class


    private IObservable<string> res;

    public string Foo
    {
                get => _foo;
                set
                {
                    this.RaiseAndSetIfChanged(ref _foo, value);
                }
    }

    public void RefreshFoo()
    {
                res.Subscribe(x => Foo = x);
    }

如果您可以使用其他软件包,我建议 ReactiveUI 它是 ReactiveCommand,它可以开箱即用地处理您的所有问题:

  var command = ReactiveCommand.CreateFromTask(async () =>
            { // define the work
                Console.WriteLine("Executing at " + DateTime.Now);
                await Task.Delay(1000);
                return "test";
            });

            command.Subscribe(res => {
                // do something with the result: assign to property
            });

            var d = Observable.Interval(TimeSpan.FromMilliseconds(500), RxApp.TaskpoolScheduler) // you can specify scheduler if you want
                .Do(_ => Console.WriteLine("Invoking at " + DateTime.Now))
                .Select(x => Unit.Default) // command argument type is Unit
                .InvokeCommand(command); // this checks command.CanExecute which is false while it is executing

输出:

Invoking at 2019-01-22 13:34:04
Executing at 2019-01-22 13:34:04
Invoking at 2019-01-22 13:34:05
Invoking at 2019-01-22 13:34:05
Executing at 2019-01-22 13:34:05

我知道这个包主要用于 UI 开发,但没有什么好的技巧,比如你可以在任何地方使用的 ReactiveCommand。

注意 await command.Execute() 默认情况下不检查命令是否可以执行。

我认为这比您的解决方案更具可读性。