我在试图处理最坏的情况时偶然发现了一个问题;在完成之前处理具有订阅的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
悍然订阅。
答案 0 :(得分:2)
LastOrDefaultAsync()
会返回IObservable
,因此它不会订阅您的序列。
await
订阅了序列。
点击IConnectableObservable.Dispose()
Disposable用于断开可观察包装器与其源的连接,导致订阅观察者停止从基础可观察序列接收值。
这意味着系统会停止发送包括OnNext
,OnError
和OnCompleted
在内的所有通知。
因此,如果您在处置await
后IConnectableObservable
,则不会收到任何通知。您可以Connect
再次hotsource
接收通知。