0

x秒ごとにデータベースからデータセットをクエリするクラスを作成しようとしています。

問題は、このオブザーバブルが以前の状態を記憶し、その状態がオブザーバブルで実際に送信されるものを決定するために使用されることです。

たとえば、私は

IObservable<SomeEntity> AddedEntities { get; private set; }
IObservable<SomeEntity> ChangedEntities { get; private set; }
IObservable<SomeEntity> DeletedEntities { get; private set; }

私の問題は、私がhttp://www.introtorx.com/を読んでいて、Subjectを使用するのは悪い考えだと彼らが言っていることです。代わりに、Observable.Createメソッドを使用する必要があります。

私の問題は、データベースに1回だけクエリを実行してから、関連情報を正しいオブザーバブルに送り返したいのですが、各サブスクライブに独自のタイマーを開始して、各IObservableへのサブスクリプションごとに5秒ごとにデータベースにクエリを実行したくないということです。

私は、変更されたものをセットとして新しいモデルを返す、1つだけのオブザーバブルを作成することで遊んだことがあります。

IObservable<EntityChangeSet> Changes {get; private set;}

public class EntityChangeSet
{
    Public IEnumerable<SomeEntity> Added {get; set;}
    Public IEnumerable<SomeEntity> Changed {get; set;}
    Public IEnumerable<SomeEntity> Deleted {get; set;}
}

そして、私はこのような解決策も受け入れています。

私がこれまでに持っているのは:

public class IntervalChangeReader
{
    // My state between ticks.
    private IEnumerable<SomeEntity> knowEntities;

    // Reads the data from the db and uses knowEntities to determine adds, changes, 
    // and deletes which are exposed through properties.
    private DbReaderAndChangeChecker checker;

    IDisposeable timerCancel;

    public IntervalChangeReader(DbReaderAndChangeChecker checker)
    {
        this.checker = checker;
    }

    public IObservable<EntityChangeSet> Changes { get; private set; }

    public Start(int seconds)
    {
        this.timerCancel = Observable.Interval(new TimeSpan.FromSeconds(seconds)).Subscribe(
            x => 
            {
                var results = this.checker.Refresh(this.knownEntities);

                // Update this.knownEntities with results.


                // Inform produce a value on the observable ????
                // I could call .OnNext If I had a subject exposed for my Observable.
            }
    }

    public Stop()
    {
        this.timerCancel.Dispose();

        // Complete on all subscriptions?
        // If I were using subjects I could just call .OnComplete here.
    }
}

サブジェクトを使用せずにObservableを作成するにはどうすればよいですか?また、結果を渡すにはどうすればよいですか?オブザーバブルへのサブスクリプションごとのタイマーではなく、1つのタイマーだけでこれをすべて実行したいと思います。

4

2 に答える 2

1

あなたが求めているのはConnectableObservableメソッドだと思います...これをいじってください(注、電話では、私の構文は少しずれている可能性があります)

public void Start(int seconds)
{
    // Every tick, generate a "changeset"
    var changeCentral =
        from tick in Observable.Interval(TimeSpan.FromSeconds(seconds))
        let results = this.checker.Refresh(this.knowEntities)
        select new EntityChangeSet(results);

    // Publish means one subscription for all "connecting" subscribers
    // RefCount means so long as one subscriber is subscribed, the subscription remains alive
    var connector = changeCentral.Publish().RefCount();
    Changes = connector;
}
于 2013-02-07T23:11:33.027 に答える
0

私は私の問題の解決策を見つけたと思います。

public class IntervalChangeReader
{
    // My state between ticks.
    private IEnumerable<SomeEntity> knowEntities;

    // Reads the data from the db and uses knowEntities to determine adds, changes, 
    // and deletes which are exposed through properties.
    private DbReaderAndChangeChecker checker;

    private EntityChangeSet lastChangeResult;

    public IntervalChangeReader(DbReaderAndChangeChecker checker)
    {
        this.checker = checker;

        // I like to use Do instead of just combining this all into Select to make the side effect obvious.
        this.Changes = Observable.Interval(TimeSpan.FromSeconds(seconds), scheduler).Do(
            x =>
                {
                    var changes = DbReaderAndChangeChecker.Refresh(this.knownXRefs);

                    // Make changes to knownXRefs which is my state.
                    this.knownXRefs.AddRange(changes.Added);
                    this.knownXRefs.RemoveAll(y => changes.Removed.Any(z => z.Id == y.Id));
                    this.knownXRefs.RemoveAll(y => changes.Changed.Any(z => z.Id == y.Id));
                    this.knownXRefs.AddRange(changes.Changed);

                    lastChangeResult = changes;
                }).Select(x => this.lastChangeResult);

            }

    public IObservable<EntityChangeSet> Changes { get; private set; }

}
于 2013-02-07T23:44:15.950 に答える