0

私は自分のコードで Observable と Rx を時々使用していますが、「プッシュ モデル」とその使用に関して、まだこの質問があります。

たとえば、次の簡単なコードがあるとします。

  private readonly static List<string> numbers = new List<string>
  {
      "1",
      "2",
      "3",
      "4",
      "5"
  };

  static void Main(string[] args)
  {
      PrintCollection();
      Console.ReadLine();
      numbers.Add("6");
      Console.ReadLine();
  }

  private static void PrintCollection()
  {
      IObservable<string> observable = numbers.ToObservable();
      observable.Subscribe<string>(x => { Console.WriteLine(x); });
  }        

プログラムが実行されると、ObservableCollection のようなものを使用して「CollectionChanged」イベントをフックしない限り、1 ~ 5 のみが出力されますが、6 は出力されません。しかし、これでは「プッシュモデル」とは一体何なのだろうか。「プッシュ モデル」とは、データ (コレクション) がイベントをサブスクライブすると、そのコレクションに新しく追加されたすべてのデータも同じイベントにサブスクライブされることを意味すると常に考えていました。

また、Observable を使用して私が見たほとんどの例は、WPF、ビューモデル駆動型の実装であるように思われます。バックエンド処理に使用したことがある人はいますか?その典型的な例は何でしょうか?

4

2 に答える 2

4

ToObservable が何をするのか混乱していると思います。基本的には、「この一連のものを参照してください。これらの値をフィードバックする新しいストリームを作成したい」と言っています。将来の変更をリッスンするなど、意味のある方法でソースリストを「ラップ」するのではなく、時間のスナップショットに近いものです。結果のオブザーバブルは、オブザーバブルが作成されたときにそのリストがどのように見えるかです。

コレクションの「ライブ ビュー」をモデル化する方法は多数あります。その 1 つは、ObservableCollection を作成し、CollectionChanged イベントへの書き込みからオブザーバブルを作成することです。ここでサブジェクトを使用することもできますが、これにより状態の概念が rx の「ステートレス」な世界に注入されます。

実際、これは強調するのに適した点です。rx ストリームは、従来の命令型/oo プログラミングよりもはるかに "機能的" な概念です。ステートマシンではなく、時間の経過とともに潜在的な値のストリームを宣言します(ただし、ステートマシンのように動作させることはできます)...時間の経過とともに必要な/必要な値を把握し、それが宣言方法ですあなたのストリーム。

ただし、このような特定のケースでは、ランダムに変化する値のストリームを宣言することは困難です。これは、他の手段 (イベント、ポーリングなど) でより適切に満たされます。

つまり、次のように書くことができます。

var numbers = new List<string>
{
    "1",
    "2",
    "3",
    "4",
    "5"
};
var source = new ObservableCollection<string>(numbers);
var query = Observable.Create<string>((obs) =>
    {
        foreach(var oldItem in source)
        {
            obs.OnNext(oldItem);
        }
        NotifyCollectionChangedEventHandler h;
        h = (o, e) => 
        {
            Console.WriteLine("Collection changed!");
            foreach(var item in e.NewItems)
            {
                obs.OnNext(item as string);
            }
        };
        source.CollectionChanged += h;
        return Disposable.Create (() => source.CollectionChanged -= h);
    });

using(query.Subscribe(Console.WriteLine))
{
    source.Add("6");
    Console.ReadLine();
}

出力:

1
2
3
4
5
Collection changed!
6
于 2013-04-01T22:55:17.733 に答える
1

サブスクリプションの前に、オブザーバブルを一緒に連結できます。

var numbers = new List<string> { "1", "2", "3", "4", "5" }.ToObservable();
numbers = numbers.Concat(new [] { "6" }.ToObservable());
numbers.Subscribe(n => Console.WriteLine(n), ex => Console.WriteLine(ex.ToString()), () => Console.WriteLine("Completed."));

出力:
1 2 3 4 5 6 完了。

サブジェクトを使用して、サブスクリプション後にアイテムを追加できます (これは、いつ/どこで発生するかを示す例です)。

var subject = new ReplaySubject<string>();
subject.OnNext("7");
subject.Subscribe(n => Console.WriteLine(n), ex => Console.WriteLine(ex.ToString()), () => Console.WriteLine("Completed."));
subject.OnNext("8");
numbers.Subscribe(n => subject.OnNext(n));
subject.OnNext("9");
subject.OnNext("10");

出力: 7 8 1 2 3 4 5 6 9 10

また、バックエンド処理に Rx を使用する例があるかどうかも尋ねました。それが主に使用されている場所だとあえて言いたいのですが、それを裏付ける確固たる証拠はありません. それは間違いなく単なる WPF ではなく、はるかに幅広いアプリケーションを備えています。これは ObservableCollection であり、データ バインディングに使用され、ObservableCollection は Rx の一部ではないため、WPF に近いと思います。

それが役立つことを願っています。

于 2013-04-02T13:34:51.533 に答える