简体   繁体   English

接收多个异步操作

[英]Rx multiple asynchronous operations

I am reading about Rx and going through some examples. 我正在阅读有关Rx的内容并通过一些示例进行研究。 I am trying to implement this: 我正在尝试实现这一点:

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

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

All this code is executed on main thread. 所有这些代码都在主线程上执行。 I removed the code where main thread (UI) consumes this lists. 我删除了主线程(UI)使用此列表的代码。 What I would like is to fetch those items in asynchronous matter, but I need results coming in predefined sequence. 我想要以异步方式获取这些项目,但是我需要按预定义顺序获得结果。

Running it in asynchronous manner is no trouble, but I am having a problem getting results in predefined sequence. 以异步方式运行它没什么问题,但是以预定义的顺序获取结果时遇到了问题。 So, I run the code, UI is displayed, after a few seconds ListA gets populated, then ListB , and finally ListC , only in this predefined sequence. 所以,我运行的代码,UI显示,几秒钟后ListA被填充,然后ListB ,最后ListC ,只有在这个预定的顺序。

How to achieve this? 如何实现呢?

Task or async might be a better fit for this model than Rx. Taskasync可能比Rx​​更适合此模型。

Nonetheless, from what I can infer for your question, use concat to connect an observable after the previous one completes: 尽管如此,根据我对您的问题的推断,在上一个完成后,可以使用concat连接一个可观察对象:

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

        fetch(() => A())
        .Concat(fetch(() => B()))
        .Concat(fetch(() => C()))
        .Subscribe();

Do this work for you? 这对您有用吗?

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;
    });

According to your question you have three collections of different types. 根据您的问题,您有三个不同类型的集合。 Obviously one cannot concatonate three streams of different types. 显然,不能合并三个不同类型的流。 I think @Enigmativity's is allmost correct but in order for it to work you need change it to: 我认为@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);
});

Another solution might be: 另一个解决方案可能是:

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;
                 });

I you want the collections as soon as they are created: 我想要集合创建后立即开始:

  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);

You could use dynamics as well ...: 您也可以使用动力学...:

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 };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM