2011-01-19 24 views
3

工作,我的代碼來設置我的Rx進行連接下列位:在Silverlight中使用的Rx爲WCF調用不TakeUntil

事件相關的定義:

public class QueryEventArgs : EventArgs 
    { 
     public SomeParametersType SomeParameters 
     { 
      get; 
      set; 
     } 

     public object QueryContext 
     { 
        get; 
      set; 
     } 
    }; 

    public delegate void QueryDelegate(object sender, QueryEventArgs e); 

    public event QueryDelegate QueryEvent; 

初始化:

  queryObservable = Observable.FromEvent<QueryEventArgs>(this, "QueryEvent"); 
      queryObservable.Subscribe((e) => 
      { 
       tbQueryProgress.Text = "Querying... "; 
       client.QueryAsync(e.EventArgs.SomeParameters, e.EventArgs.QueryContext); 
      }); 

      queryCompletedObservable = from e in Observable.FromEvent<QueryCompletedEventArgs>(client, "QueryCompleted").TakeUntil(queryObservable) select e; 

      queryCompletedObservable.Subscribe((e) => 
       { 
        tbQueryProgress.Text = "Ready"; 
        SilverlightClientService_QueryCompleted(e.Sender, e.EventArgs); 
       }, 
       (Exception ex) => 
       { 
        SetError("Query error: " + ex); 
       } 
      ); 

「客戶端」是WCF客戶端,其他所有內容都是不言自明的。

「TakeUntil」可以阻止用戶在當前正在運行的中間進行新查詢時自行踩踏自己。但是,如果我刪除了「TakeUntil」子句,而代碼正常工作,那麼如果將其放入,則查詢將永遠不會完成。

這是正確的模式?如果是這樣,我做錯了什麼?

乾杯, -Tim

回答

3

TakeUntil終止時,從它的參數接收的值,那麼你的第一個queryObservable啓動查詢,但也終止訂閱完整的事件訂閱。

更簡單的解決方案是圍繞您的實際查詢設置IObservable,然後使用Switch確保一次只運行一個查詢。

public static class ClientExtensions 
{ 
    public static IObservable<QueryCompletedEventArgs> QueryObservable(
     this QueryClient client, 
     object[] someParameters, object queryContext) 
    { 
     return Observable.CreateWithDisposable<QueryCompletedEventArgs>(observer => 
     { 
      var subscription = Observable.FromEvent<QueryCompletedEventArgs>(
        h => client.QueryCompleted += h, 
        h => client.QueryCompleted -= h 
       ) 
       .Subscribe(observer); 

      client.QueryAsync(someParameters, queryContext); 

      return new CompositeDisposable(
       subscription, 
       Disposable.Create(() => client.Abort()) 
      ); 
     }); 
    } 
} 

然後,你可以這樣做:

queryObservable = Observable.FromEvent<QueryEventArgs>(this, "QueryEvent"); 

queryObservable 
    .Select(query => client.QueryObservable(
     query.EventArgs.SomeParameters, 
     query.EventArgs.QueryContext 
    )) 
    .Switch() 
    .Subscribe(queryComplete => 
    { 
     tbQueryProgress.Text = "Ready"; 
     // ... etc 
    }); 

這就建立了一個連續流中,其中每個「查詢」事件開始,輻射從該查詢的完整事件的查詢。新的查詢自動終止以前的查詢(如果可能的話)並開始一個新的查詢。

+0

非常感謝您的快速回答,但我不知道我理解你的警告......如果新的查詢終止與該「開關」之前的查詢,你會怎麼弄,那裏有多個查詢的情況下? – Tim 2011-01-19 23:40:33

相關問題