1

私はRxについて読んでいて、いくつかの例を見ています。私はこれを実装しようとしています:

List<A> LIstA {get;set;}
List<B> LIstB {get;set;}
List<C> LIstC {get;set;}

private void GetItems()
{
    ListA = GetItemsA();
    ListB = GetItemsB();
    ListC = GetItemsC();
}

このコードはすべてメインスレッドで実行されます。メイン スレッド (UI) がこのリストを使用するコードを削除しました。私が望むのは、これらのアイテムを非同期で取得することですが、定義済みの順序で結果を取得する必要があります。

非同期で実行するのは問題ありませんが、定義済みの順序で結果を取得するのに問題があります。そのため、コードを実行すると、UI が表示され、数秒後にデータListAが取り込まれ、次にListB、最後ListCに、この事前定義された順序でのみ表示されます。

これを達成する方法は?

4

4 に答える 4

1

Taskまたはasync、Rx よりもこのモデルに適している可能性があります。

それにもかかわらず、私があなたの質問から推測できることから、concat を使用して、前のオブザーバブルが完了した後にオブザーバブルを接続します。

        Func<Action, IObservable<Unit>> fetch = 
            action => Observable.Defer(() => Observable.Start(action));

        fetch(() => A())
        .Concat(fetch(() => B()))
        .Concat(fetch(() => C()))
        .Subscribe();
于 2012-09-23T13:09:24.770 に答える
0

ダイナミクスも使用できます...:

void Main()
{
    var q =
    from @as in Observable.Start(() => GetItemsA())
    from bs in Observable.Start(() => GetItemsB())
    from cs in Observable.Start(() => GetItemsC())
    select @as.Cast<dynamic>().Concat(bs.Cast<dynamic>()).Concat(cs.Cast<dynamic>());   
    q.Subscribe(t => t.Dump()); 
}

// Define other methods and classes here
private IEnumerable<int> GetItemsA() {
    yield return 1;
    Thread.Sleep(500);
    yield return 2;
    yield return 3;
}
private IEnumerable<string> GetItemsB() {
    yield return "A";
    yield return "B";
    Thread.Sleep(1000);
    yield return "C";
}
private List<float> GetItemsC() {
    return new List<float> { 1.1f, 2.2f, 3.3f };
}
于 2012-11-21T20:33:16.633 に答える
0

これはあなたのために働きますか?

GetItemsA().ToObservable()
    .Zip(GetItemsB().ToObservable(), (a, b) => new { a, b, })
    .Zip(GetItemsC().ToObservable(), (ab, c) => new { ab.a, ab.b, c, })
    .Subscribe(abc =>
    {
        ListA = abc.a;
        ListB = abc.b;
        ListC = abc.c;
    });
于 2012-09-24T00:27:40.750 に答える
0

あなたの質問によると、異なるタイプの 3 つのコレクションがあります。明らかに、異なるタイプの 3 つのストリームを連結することはできません。@Enigmativity はほとんど正しいと思いますが、それを機能させるには、次のように変更する必要があります。

var uiScheduler = new SynchronizationContextScheduler(SynchronizationContext.Current);
ListA = new ListA();
ListB = new ListB();
ListC = new ListC();

GetItemsA().ToObservable()
.Zip(GetItemsB().ToObservable(), (a, b) => new { a, b, })
.Zip(GetItemsC().ToObservable(), (ab, c) => new { ab.a, ab.b, c, })
.ObserveOn(uiScheduler)
.Subscribe(abc =>
{
    ListA.Add(abc.a);
    ListB.Add(abc.b);
    ListC.Add(abc.c);
});

別の解決策は次のとおりです。

var a = Observable.Start(() => GetListA());
var b = Observable.Start(() => GetListB());
var c = Observable.Start(() => GetListC());

a.Zip(b, c, (x, y, z) => Tuple.Create(x, y, z))
    .ObserveOn(uiScheduler)
    .Subscribe(result =>
                 {
                   ListA = result.Item1;
                   ListB = result.Item2;
                   ListC = result.Item3;
                 });

コレクションが作成されたらすぐにコレクションが欲しい:

  a.ObserveOn(uiScheduler)
    .Do(l => ListA = l)
    .Zip(b, (la, lb) => lb)
    .ObserveOn(uiScheduler)
    .Do(l => ListB = l)
    .Zip(c, (lb, lc) => lc)
    .ObserveOn(uiScheduler)
    .Subscribe(listc => ListC = listc);
于 2012-09-24T06:28:22.090 に答える