所以我正在阅读Rx并且很难解开它。我有一个Silverlight应用程序需要异步调用6个特定服务。在过去,我们通过调用和查询userState / token来处理这个问题,以匹配响应请求,因为它们不能保证按照我们调用它们的顺序返回。但是,我怀疑Rx以更优雅的方式处理这个问题。但我无法让它发挥作用。这是我到目前为止所拥有的......
myCollection.Add(new myObject(1));
myCollection.Add(new myObject(2));
myCollection.Add(new myObject(3));
myCollection.Add(new myObject(4));
myCollection.Add(new myObject(5));
myCollection.Add(new myObject(6));
foreach (var myItem in myCollection)
{
var myObservable = Observable.FromEventPattern<MyServiceMethodCompletedEventArgs>
(
f => myServiceClient.MyServiceMethodCompleted += f,
f => myServiceClient.MyServiceMethodCompleted -= f
).Take(1).ObserveOn(SynchronizationContext.Current);
myObservable.Subscribe
(
s =>
{
if (s.EventArgs.Error == null)
{
myItem.MyProperty = s.EventArgs.Result;
}
}
);
myServiceClient.MyServiceMethodAsync(myItem);
}
我希望你能看到我在这里想要实现的目标......
我最终得到的是将所有 myObject 设置为第一次返回的调用的结果。
我确定这是愚蠢的,但我还没弄清楚。
谢谢:)
答案 0 :(得分:4)
考虑尝试使用Observable.FromAsyncPattern而不是Observable.FromEventPattern。在Silverlight(和手机)中使用FromAsyncPattern有一个技巧,因为服务代理不直接公开BeginInvoke / EndInvoke对。但是,如果您使用服务代理的接口而不是服务代理本身,则可以访问开始/结束模式:
IMyService svc = new myServiceClient();
var svcObservable = Observable.FromAsyncPattern<T, MyServiceResultArgs>
(svc.BeginMyServiceMethod, svc.EndMyServiceMethod);
现在,您可以从使用foreach(使用LINQ的反模式)切换到myCollection,使myCollection成为myCollection和服务请求之间的可观察和SelectMany,如下所示:
var requestResult = from myItem in myCollection.ToObservable()
from result in svcObservable(myItem)
select new {myItem, result};
requestResult.Subscribe(result => result.myItem.myProperty = result.result);
另外一个警告:如果你以这种方式在silverlight中使用FromAsyncPattern,结果将返回后台线程。您需要照顾teo委托给调度员。
如果您想看到这一点,请查看http://channel9.msdn.com/events/MIX/MIX11/EXT08上我的Mix演示文稿的最后20分钟左右。