使用Silverlight和Reactive Extensions管理异步服务调用

Sen*_*kwe 5 silverlight system.reactive

所以我正在读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);
}
Run Code Online (Sandbox Code Playgroud)

我希望你能看到我在这里想要实现的目标......

我最终得到的是所有myObject被设置为返回的第一个调用的结果.

我确定这是愚蠢的,但我还没弄清楚.

谢谢 :)

Jim*_*ley 4

考虑尝试 Observable.FromAsyncPattern 而不是 Observable.FromEventPattern。在 Silverlight(和手机)中使用 FromAsyncPattern 有一个技巧,因为 BeginInvoke/EndInvoke 对不是由服务代理直接公开的。但是,如果您使用服务代理的接口而不是服务代理本身,则可以访问开始/结束模式:

IMyService svc = new myServiceClient();
var svcObservable = Observable.FromAsyncPattern<T, MyServiceResultArgs>
                        (svc.BeginMyServiceMethod, svc.EndMyServiceMethod);
Run Code Online (Sandbox Code Playgroud)

现在,您可以从使用 foreach(LINQ 的反模式)切换到将 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);
Run Code Online (Sandbox Code Playgroud)

还要注意一点:如果您以这种方式在 silverlight 中使用 FromAsyncPattern,结果将在后台线程上返回。您需要将注意力委托给调度员。

如果您想查看实际效果,请查看我在http://channel9.msdn.com/events/MIX/MIX11/EXT08上的 Mix 演示的最后 20 分钟左右。