C# 为什么在这个可挂起的实现(“Rx Pausable”)中不调用OnCompleted?

C# 为什么在这个可挂起的实现(“Rx Pausable”)中不调用OnCompleted?,c#,system.reactive,rxjs,C#,System.reactive,Rxjs,我读了以下摘自奥利·里奇斯(Ollie Riches)的博客文章,我也开始思考作者的问题:为什么不通过《未完成的任务》(OnCompleted)?有人能告诉我这里发生了什么事吗?也许是一件让人尴尬的简单事情 为了方便起见,这里对代码进行了一些修改和复制(如果不能接受在这里撕毁他的代码,我向奥利道歉): 公共静态类RxExtensions { 公共静态IObservable Suspendable(此IObservable流,IObservable suspend,bool initialStat

我读了以下摘自奥利·里奇斯(Ollie Riches)的博客文章,我也开始思考作者的问题:为什么不通过《未完成的任务》(OnCompleted)?有人能告诉我这里发生了什么事吗?也许是一件让人尴尬的简单事情

为了方便起见,这里对代码进行了一些修改和复制(如果不能接受在这里撕毁他的代码,我向奥利道歉):

公共静态类RxExtensions
{
公共静态IObservable Suspendable(此IObservable流,IObservable suspend,bool initialState=false)
{
返回可观察的。创建(o=>
{
var disposable=suspend.StartWith(initialState)
.DistinctUntilChanged()
.Select(s=>s?可观察的.Empty():流)
.Switch()
.认购(o);
一次性退货;
});
}
}
var testScheduler=newtestscheduler();
var generatorCount=10;
//如果限制将硬编码为小于generatorCount的值,则会出现异常
//抛出异常,并将设置异常对象。为什么它没有在下面完成?
var生成器=可观察的。生成(1,
x=>x+1,
x=>{if(x!=11){Console.WriteLine(x);返回x;}否则{throw new ArgumentException();}},
x=>TimeSpan.FromSeconds(1),
测试调度器);
异常=空;
var completed=假;
Suspendable(newsubject()).Subscribe(=>{},e=>exception=e,()=>completed=true);
testScheduler.AdvanceBy(TimeSpan.fromMillistics(1001000.Ticks));
控制台写入线(例外);
控制台写入线(已完成);
作为记录,我想尝试生成一个可以暂停和停止的流,其区别在于暂停的流会累积事件,而Suspended只会跳过事件。它开始看起来比我预期的要复杂一些,特别是如果有人想对暂停的部分设置限制或“保存策略”。哦,好吧


您的观察者同时订阅了
暂停
流和
流。在两个流都完成之前,此组合流不会完成。基本上,您的
流已经完成,但是
可暂停的
正在等待,看是否会有更多的暂停/取消暂停信号通过。如果他们这样做,它将重新订阅源流

在源流完成时完成可暂停流是可能的,但可能会破坏方法的目的。有些东西基本上必须保持订阅源流,并在源完成时结束暂停的流。你可以这样做:

var shared = stream.Publish();
var pausable = suspend
    .StartWith(initialState)
    .TakeUntil(shared.LastOrDefaultAsync())
    .DistinctUntilChanged()
    .Select(p => p ? shared : Observable.Empty<T>())
    .Switch();
var disposable = new CompositeDisposable(pausable.Subscribe(o), shared.Connect());
return disposable;
var shared=stream.Publish();
var pausable=suspend
.StartWith(初始状态)
.TakeUntil(shared.LastOrDefaultAsync())
.DistinctUntilChanged()
.Select(p=>p?共享:Observable.Empty())
.开关();
var disposable=newcompositedisposable(pausable.Subscribe(o),shared.Connect());
一次性退货;

未发送Completed,因为您的订阅位于Observable.Empty()上,并且不是您的\u生成器的后代

因此,我使用
组合测试

public static IObservable<T> Suspendable<T>(
    this IObservable<T> source,
    IObservable<bool> pauser,
    bool initialState = false)
{
    return 
        source.CombineLatest(pauser.StartWith(initialState), 
                             (value, paused) => new {value, paused})
              .Where(_=>!_.paused)
              .Select(_=>_.value);
}
公共静态IObservable Suspendable(
这是一个可观测的来源,
IObservable暂停器,
bool initialState=false)
{
返回
source.CombineLatest(暂停器.StartWith(初始状态),
(值,暂停)=>新{值,暂停})
.Where(=>!u.暂停)
.Select(=>.value);
}

Heh,所以,这是一个简单的问题。这很好地解释了正在发生的事情。我刚刚注意到一个关于这方面的问题。这种方法感觉有点像对流施加背压的方法,只要有更奇特的东西就不那么简单了。
public static IObservable<T> Suspendable<T>(
    this IObservable<T> source,
    IObservable<bool> pauser,
    bool initialState = false)
{
    return 
        source.CombineLatest(pauser.StartWith(initialState), 
                             (value, paused) => new {value, paused})
              .Where(_=>!_.paused)
              .Select(_=>_.value);
}