压缩两个以上可观察序列的问题

时间:2018-10-04 20:00:26

标签: c# .net .net-core system.reactive

我正在寻找一个信息,为什么PostTag运算符不能使用两个以上的可观察流:

create table post (id bigint generated by default as identity, primary key (id))
create table post_tag (post_id bigint not null, tag_id bigint not null, primary key (post_id, tag_id))
create table tag (id bigint generated by default as identity, primary key (id))
alter table post_tag add constraint FKc2auetuvsec0k566l0eyvr9cs foreign key (post_id) references post
alter table post_tag add constraint FKac1wdchd2pnur3fl225obmlg0 foreign key (tag_id) references tag

Step 1
insert into tag (id) values (null)
insert into post (id) values (null)
select posttag0_.post_id as post_id1_1_0_, posttag0_.tag_id as tag_id2_1_0_ from post_tag posttag0_ where posttag0_.post_id=? and posttag0_.tag_id=?
insert into post_tag (post_id, tag_id) values (?, ?)

Step 2
insert into post (id) values (null)
insert into tag (id) values (null)
select posttag0_.post_id as post_id1_1_0_, posttag0_.tag_id as tag_id2_1_0_ from post_tag posttag0_ where posttag0_.post_id=? and posttag0_.tag_id=?
insert into post_tag (post_id, tag_id) values (?, ?)

Step 3
select tag0_.id as id1_2_0_, posts1_.post_id as post_id1_1_1_, posts1_.tag_id as tag_id2_1_1_, post2_.id as id1_0_2_, posts1_.tag_id as tag_id2_1_0__, posts1_.post_id as post_id1_1_0__ from tag tag0_ left outer join post_tag posts1_ on tag0_.id=posts1_.tag_id left outer join post post2_ on posts1_.post_id=post2_.id where tag0_.id=?
select tag0_.id as id1_2_1_, posts1_.tag_id as tag_id2_1_3_, posts1_.post_id as post_id1_1_3_, posts1_.post_id as post_id1_1_0_, posts1_.tag_id as tag_id2_1_0_ from tag tag0_ left outer join post_tag posts1_ on tag0_.id=posts1_.tag_id where tag0_.id=?
select posttag0_.post_id as post_id1_1_0_, posttag0_.tag_id as tag_id2_1_0_ from post_tag posttag0_ where posttag0_.post_id=? and posttag0_.tag_id=?
insert into post_tag (post_id, tag_id) values (?, ?)

Step 4 -- better
select posttag0_.post_id as post_id1_1_0_, posttag0_.tag_id as tag_id2_1_0_ from post_tag posttag0_ where posttag0_.post_id=? and posttag0_.tag_id=?
insert into post_tag (post_id, tag_id) values (?, ?)

我收到的错误是:

  

序列不包含任何元素

当我仅压缩两个序列时,Zip运算符可以正常工作。

下面我粘贴了堆栈跟踪:

var stream1 = Observable.Create<int>(o =>
        {
            o.OnNext(1);
            o.OnCompleted();
            return Disposable.Empty;
        });

        var stream2 = Observable.Create<int>(o =>
        {
            o.OnNext(1);
            o.OnCompleted();
            return Disposable.Empty;
        });

        var stream3 = Observable.Create<int>(o =>
        {
            o.OnNext(1);
            o.OnCompleted();
            return Disposable.Empty;
        });

        var stream4 = Observable.Create<int>(o =>
        {
            o.OnNext(1);
            o.OnCompleted();
            return Disposable.Empty;
        });

        var stream6 = stream1.Zip(stream2, stream3, stream4, (a, b, c, d) =>
        {
            return a + b + c + d;
        });

        var i = stream6.ToTask().GetAwaiter().GetResult();
        Console.WriteLine(i);
        Console.ReadKey();

1 个答案:

答案 0 :(得分:1)

在我看来,它看起来像是一个错误,或充其量是伪劣的设计。为了使事情更简单:

var stream = Observable.Return(1);

var result2 = await stream.Zip(stream, (a, b) => (a, b));
var result3 = await stream.Zip(stream, stream, (a, b, c) => (a, b, c));

Console.WriteLine($"result2 = {result2}");
Console.WriteLine($"result3 = {result3}");

result2可以工作,因为zip会产生一个值。 result3的可观察值没有产生值,因此等待失败。但是,它应该产生一个值。这是有关过载的文档:

  

每当所有可观察序列都在相应索引处生成元素时,就使用选择器功能将指定的可观察序列合并为一个可观察序列。

由于它们都在索引0处产生了一个值,因此您应该看到一个值。所以...臭虫。

有趣的是,如果您这样重新定义stream

var stream = Observable.Return(1).Delay(TimeSpan.FromMilliseconds(15));

...然后两者都起作用。错误可能与某些比赛条件有关。

我认为成对函数(具有2个可观察值)比n个重载更老,并且测试得更好。