2011-02-27 75 views
3

我讓這個異步的WebRequest調用複式倍(可根據條件兩次或三次,甚至6倍)無擴展更新UI

 var request = HttpWebRequest.CreateHttp(url); 

     var observableRequest = Observable.FromAsyncPattern<WebResponse>(
      request.BeginGetResponse, request.EndGetResponse); 

     Observable.Timeout(observableRequest.Invoke(), TimeSpan.FromSeconds(120)). 
      Subscribe(response => { HandleListResult(response); }, 
      exception => { HandleListResultTimeOut(exception); }); 

我有一個集合(列表),其中有一個綁定視圖模型到一個LisBox,我想在每個響應返回後繼續添加到集合中。

使用Reactive Extensions實現此目的的最佳做法是什麼?如果有人能夠給我看一些示例代碼,那會很棒!

在此先感謝

+0

由於您將通過引發PropertyChanged或ObservableCollection的屬性更新UI,因此最好使用ObserveOnDispatcher。 – Maciek 2011-02-27 19:07:46

回答

2

您可以翻譯網址直接流入流:

public static IObservable<Stream> RequestToStream(
     this IObservable<string> source, TimeSpan timeout) 
    { 
     return 
      from wc in source.Select(WebRequest.Create) 
      from s in Observable 
       .FromAsyncPattern<WebResponse>(wc.BeginGetResponse, 
        wc.EndGetResponse)() 
       .Timeout(timeout, Observable.Empty<WebResponse>()) 
       .Catch(Observable.Empty<WebResponse>()) 
      select s.GetResponseStream(); 
    } 

然後你需要觀察UI您responces,你需要使用.ObserveOnDispatcher(),FE:

 Observable 
      .Return("www.msdn.com") 
      .RequestToStream(TimeSpan.FromSeconds(1)) 
      .ObserveOnDispatcher() 
      .Subscribe(request => UpdateUI(Request)); 
+0

謝謝!在更新之前是否需要鎖定列表對象(它綁定到ListBox)?因爲同一個處理程序將被多次調用,並且我想知道當第二個處理程序嘗試更新List時第一個處理程序是什麼時會發生什麼已經更新它。 謝謝! – user636525 2011-02-27 22:46:11

+0

不能發生。每個更新UI的請求都會發生在同一個UI線程上 - 所以它們會被序列化。無需鎖定。 – 2011-02-27 23:44:35

+0

太棒了!謝謝 ! – user636525 2011-02-28 00:41:03

2

ReactiveUI,這是通過CreateCollection()

完成0
IObservable<string> source; // Maybe this is a Subject<string> or whatever 

myBoundCollection = source 
    .SelectMany(webServiceCall) // This is your FromAsyncPattern func 
    .CreateCollection(); // Pipe the Observable to a Collection 

ReactiveUI處理所有的ObserveOn東西,以確保它的同步和正確的線程等。這個調用立即返回一個空列表,然後隨着結果進來,集合被填充。