我在使用ReactiveExtensions时遇到了麻烦(可能很难理解),我在WinForms应用程序中连接了一个WCF服务,从以下教程开始,这就是我想出来的,而这从来没有工作过,所以我将它从常规同步方法改为异步方法,我开始改为语法错误。当我订阅它时,为什么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;
答案 0 :(得分:4)
您获得Observable<T[]>
的原因是因为ToObservable
上的Task<T>
返回Observable<T>
。必须这样做才能确保任何类型的任务都可以转换为Observable
。在这种情况下,Task用于表示返回单个值的异步函数。 Observable用于表示具有多个值的异步函数。因此,当我们将Task转换为Observable时,我们转换一个异步函数,只能返回一个值 - &gt;一个异步函数,只会返回一个值。
因此,一旦我们有一个只返回一个值的异步函数,并且该值是一个可以包含多个值的对象,我们必须创建另一个异步函数,它返回对象中包含的所有值。为此,我们可以使用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
只是意味着&#34;一次合并事物&#34 ;.)
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 :(得分:1)
我认为如果你查看ToObservable
扩展方法将任务转换为observable,这应该很简单。
看起来像这样:
IObservable<TResult> ToObservable<TResult>(this Task<TResult> task)
因此,如果您从Task<T[]>
开始,那么您将获得IObservable<T[]>
。
因此,例如,这有:
Task<int[]> task = Task.Run(() => new [] { 1, 2, 3 });
IObservable<int[]> observable = task.ToObservable();
现在,如果你想获得IObservable<int>
,那么你需要这样做:
IObservable<int> observable2 = observable.SelectMany(x => x);