Отмена обновления асинхронного свойства - PullRequest
0 голосов
/ 10 января 2019

Буду признателен за помощь в решении следующей проблемы: А есть свойство в моем классе, скажем,

string Foo {get;set;}

В классе есть функция обновления. Внутри есть длительный метод обновления

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

Как я могу избежать суммирования Task-s, когда 1000 Refresh вызывается в секунду? Дребезг? Троттлинг? Как это сделать? Rx доступен в проекте, и я использую ядро ​​dotnet 2.2.

Конструктор класса


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

Класс


    private IObservable<string> res;

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

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

1 Ответ

0 голосов
/ 22 января 2019

Если вы можете использовать другой пакет, я бы предложил 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

Я знаю, что пакет в основном используется для разработки пользовательского интерфейса, но имеет несколько приятных трюков, таких как ReactiveCommand, который вы можете использовать везде.

Остерегайтесь того, что await command.Execute() не проверяет по умолчанию возможность выполнения команды.

Я думаю, что это гораздо более читабельно, чем ваше решение.

...