【问题标题】:Cancel Observable subscription and wait for Observer to finish取消 Observable 订阅并等待 Observer 完成
【发布时间】:2017-08-13 22:59:13
【问题描述】:

有没有更好的方法来编写下面的代码来实现帖子主题中所说的内容?

我发现使用额外的Subject<long> 后,以下代码过于复杂和啰嗦,而且除非您在每个 observable 中硬编码,否则不容易创建通用解决方案。

var subject = new Subject<long>();
var cts = new CancellationTokenSource();
var observable = Observable.Interval(TimeSpan.FromSeconds(2));
var disposable = observable.Do(l => {
    {
        Console.WriteLine($"Start {l}-{DateTime.Now}");
        Thread.Sleep(2000);

        Console.WriteLine($"Stop {l}-{DateTime.Now}");
        subject.OnNext(l);
    }
}).Subscribe();
cts.Token.Register(disposable.Dispose);

Thread.Sleep(5000);
subject.Subscribe();
cts.Cancel();
subject.FirstAsync().Wait();

Console.WriteLine("Finish");

【问题讨论】:

    标签: system.reactive


    【解决方案1】:

    您最好使用Subject&lt;Unit&gt; 编写代码来表示完成。在多线程代码中使用 bool 的数组有点混乱,可能会让您感到痛苦。

    试试这个:

    var observable = Observable.Interval(TimeSpan.FromSeconds(2));
    Subject<Unit> finish = new Subject<Unit>();
    observable
        .TakeUntil(finish)
        .Do(l =>
        {
            Console.WriteLine($"Start {l}-{DateTime.Now}");
            Thread.Sleep(2000);
            Console.WriteLine($"Stop {l}-{DateTime.Now}");
        })
        .Finally(() => Console.WriteLine("Finally"))
        .Subscribe(
            l => Console.WriteLine("OnNext"),
            () => Console.WriteLine("Complete"));
    
    Thread.Sleep(5000);
    finish.OnNext(Unit.Default);
    Console.ReadLine();
    

    它产生:

    开始时间 0-2017/08/15 13:37:03 停止 0-2017/08/15 13:37:05 OnNext 开始时间 1-2017/08/15 13:37:05 停止 1-2017/08/15 13:37:07 OnNext 完全的 最后

    【讨论】:

    • 我完全同意,我已经自己发现了它,但你应该得到支持
    【解决方案2】:

    实际上取消订阅不会产生进一步的信号。正确的做法是等待完成。订阅完成后自动处理,无需进一步处理

            var observable = Observable.Interval(TimeSpan.FromSeconds(2));
            bool[] finish = {false};
            observable.TakeWhile(l => !finish[0]).Do(l => {
                Console.WriteLine($"Start {l}-{DateTime.Now}");
                Thread.Sleep(2000);
                Console.WriteLine($"Stop {l}-{DateTime.Now}");
    
            }).Finally(() => Console.WriteLine("Finally")).Subscribe(l => {
                Console.WriteLine("OnNext");
            },() => Console.WriteLine("Complete") );
            finish[0] = true;
            Console.ReadKey(true);
    

    上面的输出相同,没有额外的主题

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      相关资源
      最近更新 更多