为什么不工作的refcount所有的初始用户断开连接后? [英] Why is RefCount not working after all initial subscribers disconnect?

查看:143
本文介绍了为什么不工作的refcount所有的初始用户断开连接后?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下几点:

  [事实] 
公共无效美孚()
{
VAR的结果=新的受试对象;布尔>();
变种startCount = 0;
变种completionCount = 0;
VAR观测值=观测
.Defer(()=>
{
++ startCount;
返回result.FirstAsync();
})
。做(_ => ++ completionCount)
.Publish()
.RefCount();

//假装有很多用户在一次
VAR S1 = obs.Subscribe();
变种S2 = obs.Subscribe();
变种S3 = obs.Subscribe();

//即使如此,我们只期望能够启动一次
Assert.Equal(1 startCount);
Assert.Equal(0,completionCount);

//我们将无法完成,直到结果通过蜱
result.OnNext(真);
Assert.Equal(1,startCount);
Assert.Equal(1,completionCount);

s1.Dispose();
s2.Dispose();
s3.Dispose();

//现在尝试同样的事情再次
S1 = obs.Subscribe();
S2 = obs.Subscribe();
S3 = obs.Subscribe();

// startCount是4,而不是预期2在这里!
Assert.Equal(2,startCount);
Assert.Equal(1,completionCount);

result.OnNext(真);
Assert.Equal(2,startCount);
Assert.Equal(2,completionCount);

s1.Dispose();
s2.Dispose();
s3.Dispose();
}



我的的理解发布 + 的refcount 是到源的连接被维持,只要有至少一个用户。一旦最后一个用户断开连接,任何未来的用户将重新启动与源的连接。



正如你可以在我的测试中看到,一切都经过完美的作品第一次。但第二次,在管道内的延迟可观察对每个新订户执行一次。



我可以通过调试看到,对于第一组用户, obs._count (其计算用户)增加了每次调用订阅。但对于第二组用户,但它仍然为零。



这是怎么回事,我能做些什么来纠正我的管道?


< DIV CLASS =h2_lin>解决方案

从@ user631090答案很接近,但不正确的,所以我想我会回答我自己。



这是因为发布将立即完成新用户,如果它发布的流具有自身完成。您可以有种看到图这里的:





但是,如果图包含一个用户这本来是不错的之后的基础流完成。



要增加混乱,推迟仍然是所谓的新用户。但是,它的返回值可以简单地通过忽略发布的初始流完成的,因为



我目前还无法想出一个方法来实现我的预期使用情况。我想也许使用组播,而不是发布,根据需要创建一个新的课题。但我一直没能实现这一尚未。它似乎相当痛苦的,因为我会觉得是一种常见的用例。


Consider the following:

[Fact]
public void foo()
{
    var result = new Subject<bool>();
    var startCount = 0;
    var completionCount = 0;
    var obs = Observable
        .Defer(() =>
            {
                ++startCount;
                return result.FirstAsync();
            })
        .Do(_ => ++completionCount)
        .Publish()
        .RefCount();

    // pretend there are lots of subscribers at once
    var s1 = obs.Subscribe();
    var s2 = obs.Subscribe();
    var s3 = obs.Subscribe();

    // even so, we only expect to be started once
    Assert.Equal(1, startCount);
    Assert.Equal(0, completionCount);

    // and we won't complete until the result ticks through
    result.OnNext(true);
    Assert.Equal(1, startCount);
    Assert.Equal(1, completionCount);

    s1.Dispose();
    s2.Dispose();
    s3.Dispose();

    // now try exactly the same thing again
    s1 = obs.Subscribe();
    s2 = obs.Subscribe();
    s3 = obs.Subscribe();

    // startCount is 4 here instead of the expected 2!
    Assert.Equal(2, startCount);
    Assert.Equal(1, completionCount);

    result.OnNext(true);
    Assert.Equal(2, startCount);
    Assert.Equal(2, completionCount);

    s1.Dispose();
    s2.Dispose();
    s3.Dispose();
}

My understanding of Publish + RefCount is that a connection to the source is maintained as long as there is at least one subscriber. Once the last subscriber disconnects, any future subscriber will re-initiate the connection to the source.

As you can see in my test, everything works perfectly the first time through. But the second time, the deferred observable inside the pipeline is executed once for every new subscriber.

I can see via the debugger that for the first group of subscribers, obs._count (which counts subscribers) increases for each call to Subscribe. But for the second group of subscribers, it remains zero.

Why is this happening and what can I do to rectify my pipeline?

解决方案

The answer from @user631090 is close, but incorrect, so I thought I'd answer myself.

It's because Publish will immediately complete new subscribers if the stream it published has itself completed. You can kind of see that in the diagram here:

But it would have been nice if the diagram included a subscriber after the underlying stream completes.

To add to the confusion, Defer is still called for new subscribers. But its return value is simply ignored by Publish because of the initial stream completing.

I'm as yet unable to come up with a way to implement my intended use case. I thought perhaps using Multicast rather than Publish, creating a new subject as necessary. But I haven't been able to achieve that yet. And it seems rather painful for what I would think is a common use case.

这篇关于为什么不工作的refcount所有的初始用户断开连接后?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆