Реактивные расширения — выполнение функции в коллекции только по одному

#c# #.net #multithreading #system.reactive

#c# #.net #многопоточность #system.reactive

Вопрос:

Есть ли способ принудительно использовать блок кода в Observable.Начать выполнять элементы один за другим?

Просто для ясности, например, когда он завершается с индексом 0, только тогда он будет выполняться с индексом 1 и так далее…

     public void Click()
    {
        this.strings.ToObservable().Subscribe(
            x =>
            {
                Observable.Start(
                    () =>
                    {
                        //long operation
                        BarValue  ;
                    });
            });
    }
  

Комментарии:

1. почему бы вам просто не использовать IEnumerable? Кажется, вы все равно хотите работать на основе извлечения (ну, ваш код)

2. вы правы. у меня есть другая реализация с TaskFactory и простым ForEach в списке.

Ответ №1:

Вот и все:

 this.strings.ToObservable()
    .Select(x => Observable.Defer(() => Observable.Start(() => { /* ... */ })))
    .Concat();
  

Мы выбираем каждую строку в наблюдаемый объект, который при подписке запускает задачу и выполняет некоторую работу (т. Е. Никакая работа не выполняется немедленно, в отличие от вызова Observable .Запуск, вот почему нам нужен Defer, чтобы остановить запуск метода Start).

Затем мы объединяем все вместе с помощью Concat, что гарантирует сохранение исходного порядка потока путем одновременного запуска только одного элемента.

Комментарии:

1. Вы могли бы просто использовать ToEnumerable , если только вы не делаете что-то асинхронное. В этом случае вы могли бы просто использовать ToAsyncEnumerable .

2. Наблюдаемый. Запуск означает, что они уже делают что-то асинхронное

3. Протокол поддерживает асинхронность, но не требует фактического выполнения асинхронных операций. Без подробностей о реализации это может быть просто return Observable.Return<int>(1) .

4. Нет, нет. Я это понимаю. Я хочу сказать, что функция, вызываемая с помощью Start , может не выполнять ничего асинхронного, и поэтому все использование Start может быть неуместным. Очевидно, что сами вызовы могут потребоваться по другим причинам… Я просто указываю, что Rx — не единственный способ сделать это.

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