反应性延伸的可观察模式

asb*_*asb 6 .net c# system.reactive

我试图理解下面的代码试图使用反应式扩展

 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");
    }
Run Code Online (Sandbox Code Playgroud)

如果我在输入框中输入SEARC,则输出显示

  • OnNext SE
  • OnNext SEA
  • OnNext SEA
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEAR
  • OnNext SEARC
  • OnNext SEARC
  • OnNext SEARC
  • OnNext SEARC

    1. 为什么"S"不会触发OnNext?
    2. 为什么OnCompleted从未被调用过?
    3. 为什么OnNext在第n个字符上调用了n-1次?

Eni*_*ity 3

您似乎正在订阅searchScrip_TextChanged处理程序中的可观察对象。

这意味着第一次被searchScrip_TextChanged调用S已经发生在你连接可观察对象之前。所以当然不会火。

但既然 已S被点击,您就有了一个订阅,因此当您E键入 时,您会得到一个SE. 但由于searchScrip_TextChanged处理程序也被调用,E您现在有两个可观察的订阅。

因此,当A键入 时,您会得到两个SEA,因为您有两个可观察量。但再次searchScrip_TextChanged需要的是,A所以现在你有三个可观察量。

等等等等等等

事件不会自动完成。您需要手动处置订阅才能结束它们。这应该是有意义的,因为这就是您必须对要停止的正常事件处理程序执行的操作。

您应该在加载表单时创建可观察对象,以便它被创建一次。

它应该看起来像这样:

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"));
Run Code Online (Sandbox Code Playgroud)