2011-07-21 50 views
5

因此,我正在閱讀Rx並且難以對其進行維護。我有一個Silverlight應用程序需要對異步的特定服務進行6次調用。在過去,我們通過調用和查詢userState/token來匹配響應和請求來處理這個問題,因爲它們不能保證以我們稱之爲的順序返回。不過,我懷疑Rx以更加優雅的方式處理這個問題。但我無法讓它工作。這裏是我迄今爲止...使用Silverlight和反應式擴展管理異步服務調用

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的的幸福的設置爲返回的第一個調用的結果。

我敢肯定這是愚蠢的,但我還沒有弄明白。

謝謝:)

回答

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和服務請求之間可觀察到的和的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這種方式,結果就會回來背景線。您需要注意將其委託給調度員。

如果你想看到這個在行動,請查看我的Mix演示文稿的最後20分鐘左右,在http://channel9.msdn.com/events/MIX/MIX11/EXT08

+0

謝謝!這工作,並看起來不錯,以引導:-)我想知道,要將搜索結果編組回UI線程,我不能只是將最後一行更改爲requestResult.ObserveOn(SynchronizationContext.Current).Subscribe(...) ? – Senkwe

+0

是在ObserveOn上。另外,如果你添加一個引用到相應的System.Reactive.???.Threading庫,你可以使用requestResult.ObserveOnDispatcher()。訂閱(...) –

+0

好的答案 - 因爲Jim間接顯示使用查詢語法,密鑰發出請求是使用SelectMany –