ReactiveExtensions и асинхронные методы обслуживания?

1

У меня возникают проблемы (возможно, проблемы с пониманием) с помощью ReactiveExtensions, у меня есть служба WCF, с которой я подключаюсь в приложении WinForms, и из следующих руководств. Это то, что я придумал, и это никогда не срабатывало, поэтому я изменил его с регулярные синхронные методы для асинхронных, я вместо этого начал синтаксические ошибки. Почему Task<T[]>.ToObservable() дает мне T[] когда я подписываюсь на него? У меня может быть намного больше, чем это неправильно. Спасибо за любую помощь!

        var users =
            _chatServiceClient.GetAllUsersAsync()
                .ToObservable()
                .SubscribeOn(TaskPoolScheduler.Default)
                .ObserveOn(this)
                .Throttle(TimeSpan.FromMilliseconds(500))
                .DistinctUntilChanged();

        var messages =
            _chatServiceClient.GetNewMessagesAsync(_me)
                .ToObservable()
                .SubscribeOn(TaskPoolScheduler.Default)
                .ObserveOn(this)
                .DistinctUntilChanged()
                .Throttle(TimeSpan.FromMilliseconds(100))
                .Subscribe(m => chatRichTextBox.AppendText(string.Format("{0}:{1}: {2}", m.Date, m.User, m.Content)));

        userList.DataSource = users;
Теги:
wcf
task
system.reactive
.net-4.5

2 ответа

4
Лучший ответ

Причина, по которой вы получаете Observable<T[]> заключается в том, что ToObservable в Task<T> возвращает Observable<T>. Он должен сделать это, чтобы любой тип задачи мог быть преобразован в Observable. В этом случае задача используется для представления асинхронной функции, которая возвращает одно значение. Observable используется для представления асинхронной функции с несколькими значениями. Итак, когда мы конвертируем задачу в наблюдаемую, мы преобразуем асинхронную функцию, которая может возвращать только одно значение → асинхронную функцию, которая будет возвращать только одно значение.

Поэтому, если у нас есть асинхронная функция, которая возвращает только одно значение, и это значение является объектом, который может содержать несколько значений, мы должны создать другую асинхронную функцию, которая возвращает все значения, содержащиеся в объекте. Для этого мы можем использовать SelectMany.

Task<T[]> taskOfCollection = ...;

Observable<T[]> obsOfCollection = TaskOfCollection.ToObservable();

Observable<T> obsOfItems = obsOfCollection.SelectMany(x => x.ToObservable());

Однако, поскольку x является массивом, он является Enumerable, а SelectMany знает, как обрабатывать Enumerable, поэтому мы можем просто вернуть x.

Observable<T> obsOfItems = obsOfCollection.SelectMany(x => x);

Вышесказанное - это просто длинный способ Merge.

Observable<T> obsOfItems = obsOfCollection.Merge();

И поскольку из obsOfCollection возвращается только один элемент, Concat работает тоже (Concat просто означает "Слияние на предмет за раз").

Observable<T> obsOfItems = obsOfCollection.Concat();

Итак, ваше окончательное выражение становится следующим:

Observable<T> obs = task.ToObservable().Merge();
// or
Observable<T> obs = task.ToObservable().Merge(1);
// or
Observable<T> obs = task.ToObservable().Concat();

Причина:

Причина ToObservable в Task<T[]> не возвращает Observable<T>, потому что для этого нет перегрузки. Однако причина, по которой перегрузка не возникает, заключается в том, что она не позволит пользователям использовать Observable для await множества вещей.

1

Я думаю, что это должно быть достаточно простым, если вы посмотрите на ToObservable расширения ToObservable для преобразования задачи в наблюдаемую.

Это выглядит так:

IObservable<TResult> ToObservable<TResult>(this Task<TResult> task)

Поэтому, если вы начинаете с Task<T[]> тогда вы получите IObservable<T[]> out.

Так, например, это имеет место:

Task<int[]> task = Task.Run(() => new [] { 1, 2, 3 });

IObservable<int[]> observable = task.ToObservable();

Теперь, если вы хотите получить IObservable<int>, вам нужно сделать следующее:

IObservable<int> observable2 = observable.SelectMany(x => x);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню