【问题标题】:Reactive program doesn't terminate after wait等待后反应程序不会终止
【发布时间】:2019-04-08 15:19:09
【问题描述】:

我希望下面的程序在您点击z 之前回显任何按键,但是当您点击z 时它不会终止,并且只会回显每隔一个按键。我做错了什么?

using System.Reactive;
using System.Reactive.Linq;

public class Printer : IObserver<char>
{ 
    public void OnNext(char x)
    {
        Console.WriteLine(x);
    }

    public void OnError(Exception x)
    {

    }
    public void OnCompleted()
    {

    }
}

class Program
{
    static IObservable<char> keys = Observable.Defer(() =>Observable.Start(() =>Console.ReadKey().KeyChar)).Repeat(); //https://stackoverflow.com/questions/10675451/iobservable-of-keys-pressed
    public static int Main()
    {
        IObserver<char> x = new Printer();
        keys.Subscribe(x);
        keys.Where(b => b == 'z').Wait();
        return 0;
    }
}

【问题讨论】:

  • 您正在创建多个订阅。如果你想分享按键,你需要发布 observable。

标签: c# system.reactive


【解决方案1】:

好的,所以两个问题,都是分开的:

  1. 你这里有一个cold observable。 只有当你开始观察它时,它才会产生价值。 相反,每次订阅它时,它都代表一个新的流——类似于IEnumerable 每次尝试获取项目时的评估方式。如果您在Observable.Defer 中放置一个断点,您可以清楚地看到这一点。

    您可以拥有这两个流share just one subscription to the source,即按键可观察。所以我们将冷的 observable 转换成热的。

  2. Wait 方法是:

    等待可观察序列完成并返回最后一个元素 序列。如果序列以 OnError 通知终止,则异常 被抛出。

    所以它会等到序列完成,即,OnCompleted 已被沿可观察链调用。因此,我们使用TakeUntil 以便序列仅在满足条件时完成(按'z')。

        public static int Main()
        {
            var keys_stream = keys.Publish().RefCount(); // share
    
            IObserver<char> x = new Printer();
            keys_stream.Subscribe(x);
            keys_stream.TakeUntil(b => b == 'z').Wait(); //wait until z
            return 0;
        }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2013-12-27
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多