簡體   English   中英

反應性擴展的可觀察模式

[英]Observable pattern on reactive extension

我試圖理解下面的代碼嘗試使用反應式擴展

 IObservable<string> textChangedObservable =
            Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged")
                .Select(evt => ((TextBox) sender).Text);

 textChangedObservable.Subscribe(OnNext, OnCompleted);

private void OnNext(string s)
    {
        System.Diagnostics.Debug.Print("OnNext " + s + "\n");
    }

    private void OnCompleted()
    {
        System.Diagnostics.Debug.Print("OnCompleted " + "\n");
    }

如果我在輸入框中輸入SEARC,輸出看起來

  • OnNext SE
  • OnNext海
  • OnNext海
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEARC
  • OnNext SEARC
  • OnNext SEARC
  • OnNext SEARC

    1. 為什么“ S”不觸發OnNext?
    2. 為什么從不調用OnCompleted?
    3. 為什么OnNext在第n個字符上稱為n-1次?

您似乎在searchScrip_TextChanged處理程序中訂閱了observable。

這意味着在連接可觀察對象之前 ,第一次發生searchScrip_TextChanged被稱為S情況已經發生。 因此,它當然不會觸發。

但是,既然S命中了,您就有一個訂閱,所以當鍵入E時,您將得到一個SE 但是,由於searchScrip_TextChanged處理函數也被調用為E您現在對可觀察對象也有兩個訂閱。

因此,當鍵入A時,您將獲得兩個SEA因為您有兩個可觀察值。 但是,再次為A調用了searchScrip_TextChanged ,因此現在您有了三個可觀察到的對象。

等等等等

活動不會自動完成。 您需要手動處理訂閱以使訂閱結束。 這應該是有道理的,因為這就是您要停止的常規事件處理程序所要做的。

加載表單時,應該創建可觀察對象,以便創建一次。

它看起來應該像這樣:

IObservable<string> textChangedObservable =
        Observable.FromEventPattern<TextChangedEventArgs>(searchScrip, "TextChanged")
            .Select(evt => searchScrip.Text);

IDisposable subscription =
    textChangedObservable
        .Subscribe(
            s => Debug.Print("OnNext " + s + "\n"),
            s => Debug.Print("OnCompleted\n"));

這里的問題確實與Rx無關。

1:為什么“ S”不觸發OnNext?

因為您訂閱的TextChanged事件沒有在第一個S上觸發。

2:為何從未調用OnCompleted?

將.NET事件包裝為IObservable<T> ,永遠不會收到OnErrorOnCompleted通知。 .NET事件沒有錯誤或完成的概念。

如果有兩個事件,一個用於值,一個用於完成,則可以將它們組合如下:

var values = Observable.FromEvent(...);
var completion = Observable.FromEvent(...);
var query = values.TakeUntil(completion);

現在query將產生適當的OnCompleted通知。

3:為什么OnNext在第n個字符上稱為n-1次?

因為您訂閱的TextChanged事件以這種方式觸發。 正如@ Kari-Antti指出的那樣,這可能是使用“路由屬性”事件的副作用。

也許是因為您使用過RoutedPropertyChangedEventArgs?

如果使用PropertyChangedEventHandler怎么辦?

Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                h => yourModel.propertyChanged += h,
                h => yourModel.propertyChanged -= h)
            .Where(x => x.EventArgs.PropertyName = "your_property_name");
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM