处置IConnectableObservable不会发送OnComplete

时间:2016-04-08 09:33:05

标签: c# system.reactive

我在试图处理最坏的情况时偶然发现了一个问题;在完成之前处理具有订阅的IConnectableObservable

我写了一个人为的例子来重现这个问题。

var hotSource = Observable
    .Return(1)
    .Delay(TimeSpan.FromMilliseconds(500))
    .Publish();

var disposable = hotSource.Connect();

这是我的热点观察。我添加了一个延迟,以便我可以在它触发值之前订阅它。

下面我返回一个等待的observable,它应该允许我等到hotSource完成。我相信我应该赞同这一点

var awaitable = hotSource
    .Do((Console.WriteLine))
    .Finally(() => Console.WriteLine("Complete"))
    .LastOrDefaultAsync();

现在,如果我立即处置,那么等待我的订阅:

disposable.Dispose();
await awaitable;

它只是完全挂起应用程序,永远不会调用Finally

我希望我的awaitable返回OnCompleted或最差OnError ObjectDisposedException。此外,如果您在订阅后连接,它仍然会挂起。有什么想法吗?

[更新]

考虑supertoi的答案(我在处理之前没有订阅)我在处理之前用明确的订阅重新表述了这个问题。

var mutex = new SemaphoreSlim(0);

var hotSource = Observable
    .Return(1)
    .Delay(TimeSpan.FromMilliseconds(500))
    .Publish();

var subscription = Observable.Create(
    (IObserver<int> observer) =>
    {
        Console.WriteLine("Subscribed");
        return hotSource.Subscribe(observer);
    })
    .Finally(() => mutex.Release())
    .Subscribe(Console.WriteLine);

hotSource
    .Connect()
    .Dispose();

await mutex.WaitAsync();
Console.WriteLine("Complete");

这再次停止,但是在它被处置之前它的IConnectableObservable悍然订阅。

1 个答案:

答案 0 :(得分:2)

LastOrDefaultAsync()会返回IObservable,因此它不会订阅您的序列。 await订阅了序列。

点击IConnectableObservable.Dispose()

上的the comment
  

Disposable用于断开可观察包装器与其源的连接,导致订阅观察者停止从基础可观察序列接收值。

这意味着系统会停止发送包括OnNextOnErrorOnCompleted在内的所有通知。

因此,如果您在处置awaitIConnectableObservable,则不会收到任何通知。您可以Connect再次hotsource接收通知。