2011-07-21 16 views
5

Bu yüzden Rx'i okuyorum ve zor bir zaman geçiriyorum. Belirli bir hizmete eşzamansız olarak 6 çağrı yapması gereken bir Silverlight uygulamasına sahibim. Eski günlerde, çağrıları yaparak ve kullanıcı adı/belirtecini sorgulayarak, istekte bulunma sırasına göre yanıt vermeyi kabul etmediklerinden, istekle yanıtı eşleştirerek halledebiliriz. Ancak, Rx'in bunu daha zarif bir şekilde ele aldığından şüpheleniyorum. Ama işe yaramayacağım. Ben bugüne kadar ne İşte Sana burada elde etmek çalışıyorum görebilirsiniz umutSilverlight ve Reaktif Uzantıları kullanarak async servis çağrılarını yönetme

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); 
} 

...

Ben ile bitirmek ne

myObject 'in varlığının bütün olduğunu ... var geri dönen ilk aramanın sonucuna ayarlayın.

Eminim aptalca bir şey ama bunu henüz çözemedim.

Teşekkür :)

cevap

4

Observable.FromEventPattern yerine Observable.FromAsyncPattern denemeyi düşünün. BeginInvoke/EndInvoke çifti doğrudan hizmet proxy'si tarafından açıklanmadığından, Silverlight'ta (ve telefonda) FromAsyncPattern'i kullanmanın bir hilesi var. Eğer servis vekil kendisinden ziyade hizmet proxy için arayüz kullanımı Ancak, Başlamadan/bitiş deseni erişebilirsiniz: Şimdi

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

, foreach (LINQ ile bir anti-desen) kullanarak geçiş yapabilirsiniz myCollection ve hizmet isteği arasında bir gözlemlenebilir ve SelectMany içine myCollection yapmaya şöyle: dikkatli

var requestResult = from myItem in myCollection.ToObservable() 
        from result in svcObservable(myItem) 
        select new {myItem, result}; 

requestResult.Subscribe(result => result.myItem.myProperty = result.result); 

bir başka kelimeler: Eğer SILVERLIGHT FromAsyncPattern bu şekilde kullanırsanız, sonuç bir arka plan üzerinde geri gelecek iplik. Sorumlu temsilciye geri dönme yetkisi devretmeniz gerekecek.

Eğer bunu çalışırken görmek istiyorsanız, Mix sunumumun son 20 dakikasını http://channel9.msdn.com/events/MIX/MIX11/EXT08 numaralı telefondan kontrol edin.

+0

Teşekkür ederim! Bu çalışır ve boot için harika görünüyor :-) merak ediyorum, sonuçları UI iş parçacığına geri marshal için, sadece requestResult.ObserveOn (SynchronizationContext.Current) .Subscribe (...) için son satırı değiştiremezsiniz ? – Senkwe

+0

Evet ObserveOn. Alternatif olarak, uygun System.Reactive.???.Threading kitaplığına bir başvuru eklerseniz, requestResult.ObserveOnDispatcher() öğesini kullanabilirsiniz .. Abone (...) –

+0

Büyük yanıt - Jim dolaylı sorgu sözdizimini kullanarak gösterir, anahtar istekleri vermek için SelectMany kullanıyor –