2011-07-21 30 views
5

Vì vậy, tôi đang đọc trên Rx và gặp khó khăn trong thời gian rãnh. Tôi có một ứng dụng Silverlight cần thực hiện 6 cuộc gọi đến một dịch vụ cụ thể một cách không đồng bộ. Trong những ngày cũ, chúng tôi sẽ xử lý điều này bằng cách thực hiện cuộc gọi và truy vấn userState/token để khớp với phản hồi với yêu cầu vì chúng không được đảm bảo trả lại theo thứ tự mà chúng tôi đã gọi. Tuy nhiên, tôi nghi ngờ Rx xử lý điều này một cách thanh lịch hơn rất nhiều. Nhưng tôi không thể làm cho nó hoạt động được. Dưới đây là những gì tôi có cho đến nay ...Quản lý các cuộc gọi dịch vụ không đồng bộ bằng Silverlight và Tiện ích mở rộng phản ứng

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

Tôi hy vọng bạn có thể thấy những gì tôi đang cố gắng để đạt được ở đây ...

Những gì tôi kết thúc với là tất cả của con người myObject 's được đặt thành kết quả của cuộc gọi đầu tiên trả về.

Tôi chắc chắn đó là điều gì đó ngớ ngẩn nhưng tôi chưa thể tìm ra.

Cảm ơn :)

Trả lời

4

Cân nhắc thử Observable.FromAsyncPattern thay vì Observable.FromEventPattern. Có một thủ thuật để sử dụng FromAsyncPattern trong Silverlight (và điện thoại) bởi vì cặp BeginInvoke/EndInvoke không được tiếp xúc trực tiếp bởi proxy dịch vụ. Tuy nhiên, nếu bạn sử dụng giao diện cho proxy dịch vụ chứ không phải là dịch vụ proxy bản thân, bạn có thể truy cập bắt đầu/kết thúc mẫu:

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

Bây giờ, bạn có thể chuyển từ việc sử dụng foreach (một mô hình chống với LINQ) để làm myCollection của bạn thành một thể quan sát được và SelectMany giữa myCollection và yêu cầu dịch vụ như sau:

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

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

một thêm lời cảnh báo: Nếu bạn sử dụng FromAsyncPattern trong Silverlight cách này, kết quả sẽ trở lại trên một nền tảng chủ đề. Bạn sẽ cần phải chăm sóc teo đại biểu lại cho điều phối viên.

Nếu bạn muốn thấy điều này hoạt động, hãy xem 20 phút cuối cùng của bản trình bày Bản trình bày của tôi tại http://channel9.msdn.com/events/MIX/MIX11/EXT08.

+0

Thankyou! Điều này hoạt động và sẽ rất tốt để khởi động :-) Tôi tự hỏi, để soái kết quả trở lại thread UI, tôi không thể chỉ cần thay đổi dòng cuối cùng để requestResult.ObserveOn (SynchronizationContext.Current) .Subscribe (...) ? – Senkwe

+0

Có trên ObserveOn. Ngoài ra, nếu bạn thêm một tham chiếu đến thư viện System.Reactive.????Thông thống thư viện thích hợp, bạn có thể sử dụng requestResult.ObserveOnDispatcher() Đăng ký (...) –

+0

Câu trả lời hay - như Jim gián tiếp hiển thị bằng cú pháp truy vấn, khóa để phát hành các yêu cầu đang sử dụng SelectMany –

Các vấn đề liên quan