Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 同步多个可观测流_.net_System.reactive - Fatal编程技术网

.net 同步多个可观测流

.net 同步多个可观测流,.net,system.reactive,.net,System.reactive,我对被动扩展非常陌生,因此这可能是一个新手问题,但我有以下场景: 我从数据库中获取3个IEnumerable列表(不同类型),并填充一个视图模型。不过,我希望在所有列表完成加载后协调订阅以触发某些事件。这在被动扩展中是可能的,还是我的想法是错误的?代码块如下所示: GetCustomers() .ToObservable(Scheduler.Default) .Buffer(20).ObserveOn(SynchronizationContext.Current) .Su

我对被动扩展非常陌生,因此这可能是一个新手问题,但我有以下场景:

我从数据库中获取3个IEnumerable列表(不同类型),并填充一个视图模型。不过,我希望在所有列表完成加载后协调订阅以触发某些事件。这在被动扩展中是可能的,还是我的想法是错误的?代码块如下所示:

GetCustomers()
    .ToObservable(Scheduler.Default)
    .Buffer(20).ObserveOn(SynchronizationContext.Current)
    .Subscribe(View.Model.AddRange);
GetCountries()
    .ToObservable(Scheduler.Default)
    .Buffer(20).ObserveOn(SynchronizationContext.Current)
    .Subscribe(View.Model.AddRange);
GetTransports()
    .ToObservable(Scheduler.Default)
    .Buffer(20).ObserveOn(SynchronizationContext.Current)
    .Subscribe(View.Model.AddRange);
var plan =
    Observable.Start(() => GetCountries())
        .And(Observable.Start(() => GetCustomers()))
        .And(Observable.Start(() => GetTransports()))
        .Then((countries, customers, transports)
            => new { countries, customers, transports });

var query =
    Observable.When(new [] { plan });

query
    .Subscribe(cct =>
    {
        View.Model.AddRange(cct.countries);
        View.Model.AddRange(cct.customers);
        View.Model.AddRange(cct.transports);
    });

我不知道为什么要将一个已经同步的可枚举项更改为一个可观察项,但在Rx习惯用法中,您可以:

Observable.Merge(Add(GetCustomers()), Add(GetCountries())..., Add(GetTransports()))
           .Subscribe(() => { }, Completed);
Add可以是:

    private IObservable<Unit> Add<T>(IObservable<T> o)
    {
        return o.Buffer(20)
                .ObserveOn(SynchronizationContext.Current)
                .Do(View.Model.AddRange)
                .Select(_ => Unit.Default);
    }
private IObservable添加(IObservable o)
{
返回o.缓冲器(20)
.ObserveOn(SynchronizationContext.Current)
.Do(View.Model.AddRange)
.Select(=>Unit.Default);
}

您可以尝试使用可观察连接。大概是这样的:

GetCustomers()
    .ToObservable(Scheduler.Default)
    .Buffer(20).ObserveOn(SynchronizationContext.Current)
    .Subscribe(View.Model.AddRange);
GetCountries()
    .ToObservable(Scheduler.Default)
    .Buffer(20).ObserveOn(SynchronizationContext.Current)
    .Subscribe(View.Model.AddRange);
GetTransports()
    .ToObservable(Scheduler.Default)
    .Buffer(20).ObserveOn(SynchronizationContext.Current)
    .Subscribe(View.Model.AddRange);
var plan =
    Observable.Start(() => GetCountries())
        .And(Observable.Start(() => GetCustomers()))
        .And(Observable.Start(() => GetTransports()))
        .Then((countries, customers, transports)
            => new { countries, customers, transports });

var query =
    Observable.When(new [] { plan });

query
    .Subscribe(cct =>
    {
        View.Model.AddRange(cct.countries);
        View.Model.AddRange(cct.customers);
        View.Model.AddRange(cct.transports);
    });

它并行运行,最后一次得到所有结果。

这将如何工作,因为
T
对于所有三个观察对象都是不同的?@casperOne我不知道他的内部逻辑是什么,但是OP调用了
View.Model.AddRange
。在不同类型的情况下,它们可以通过
Get()…Do(action)来缩小。选择(=>newunit())
。根据澄清,这不起作用,因为
t
对于所有观察对象都是不同的(对于
AddRange
)有重载)。@casperOne我在上面的评论中提到了另一种解决方案。我添加了编辑答案来反映这一点。每个
IEnumerable
是否在不同的
T
上工作?是的,它们都有不同的类型。此外,View.Model.AddRange对三种不同类型都有重载。我认为OP希望列表并行加载,但知道它们何时全部完成。是的@Asti,这将并行加载列表,但仅在加载所有列表时显示它们。