2

ステート マシンのような状態を追跡する Observable があります。

物事が特定の状態にあることを検出する Observable のサブスクライバーがあり、Observable で OnNext() を効果的に呼び出して、物事を新しい状態にプッシュする必要があります!

これは、一度に 1 つの OnNext() しか実行できないという Rx の原則に違反しています。これを回避する良い方法はありますか?現在の OnNext() の伝播が完了した直後に OnNext() をスケジュールするように?

4

2 に答える 2

2

制御システム理論では、このタイプのシステムはフィードバックを持つ制御ループです。システムの入力は出力に依存するため、従来の分析には抵抗します。出力は連続関数である可能性があります。

Observables (本質的に値の離散ストリーム) で同じことを行うことができます。つまり、制御システムを宣言的に表現できます。ただし、C# のセマンティクスにより、実装はあまり洗練されていません。(F# には再帰バインディングのオプションがあります)。

まず、フィードバック ループを記述するためのクロージャを定義する必要があります。

    public delegate IObservable<T> Feedback<T>(IObservable<T> feedback, out IObservable<T> output);
    public static IObservable<T> FeedbackSystem<T>(Feedback<T> closure)
    {
        IObservable<T> source = Observable.Empty<T>(), output;
        source = closure(Observable.Defer(() => source), out output);
        return output;
    }

上記を使用して、ランダムエラーが速度に導入された場合でも、100 まで加速し、それ以下の速度を維持する速度ガバナーの実装例を次に示します。

    var system =
    FeedbackSystem((IObservable<double> acceleration, out IObservable<double> velocity) =>
    {
        //Time axis: moves forward every 0.1s
        double t = 0.1; var timeaxis = Observable.Interval(TimeSpan.FromSeconds(t));

        velocity = acceleration.Sample(timeaxis)                //move in time
                               .Scan((u, a) => u + a * t)   //u' = u + at
                               .Select(u => u + new Random().Next(10))  //some variations in speed
                               .Publish().RefCount();                   //avoid recalculation

        //negative feedback
        var feedback = velocity.Select(u => 0.5 * (100 - u));

        return feedback.Select(a => Math.Min(a, 15.0))  //new limited acceleration
                       .StartWith(0);                   //initial value          
    });

    system.Subscribe(Console.WriteLine);

ステートマシンのケースは、同じ方法で入力を出力に依存させることで可能になります。

于 2013-02-01T00:20:09.480 に答える
0

オフハンドでは、おそらく「何か他のことをしたい」と思います。つまり、包含クラスなどにメソッドがあるように、オブザーバブルに別のインジェクションポイントがあります。PushState(...)

いずれにせよ、「次のことを教えてあげる」のセマンティクスを保持するには、を使用IObservableするSubject<T>か、作成時に注入ルートを指定します。Observable.Create

Subject<T>「非純度」であるため、多くの人から見下されていますが)

于 2013-01-30T18:32:09.340 に答える