使用Rx .NET从另一个可观察的对象通知异步主题

时间:2018-10-09 17:33:30

标签: c# system.reactive rx.net

我试图通知从另一个可观察对象订阅Subject _sub的侦听器,然后在Do处理程序中记录一些消息。我正在呼叫OnNext,如果_sub不是异步的,那么一切都会正常进行。这里的问题是,没有第一个可观察到的OnNextAsync函数。最好的方法是什么?

 class Program
        {
            private static Subject<int> _sub = new Subject<int>();

            static void Main(string[] args)
            {
                _sub.SelectMany(async _ =>
                {
                    Console.WriteLine("SUB START: " + _);
                    await Task.Delay(3000);
                    Console.WriteLine("SUB END: " + _);
                    return 1;
                }).Subscribe();


                Start();
            }

            public static void Start()
            {
                int count = 0;
                Observable.Interval(TimeSpan.FromSeconds(5)).Select(x =>
                {
                    Console.WriteLine("START INTERVAL");
                    _sub.OnNext(count++); //onNext is not awaitable
                    Console.WriteLine("END INTERVAL");
                    return 1;
                })
                .Do(_ => Console.WriteLine("ALL FINISHED"))
                .Subscribe();

                Console.WriteLine("READLINE");
                Console.ReadLine();
            }

        }

结果:

READLINE
START INTERVAL
SUB START: 0
END INTERVAL
ALL FINISHED
SUB END: 0

预期结果:

READLINE
START INTERVAL
SUB START: 0
SUB END: 0
END INTERVAL
ALL FINISHED

2 个答案:

答案 0 :(得分:0)

可观察对象不应该依赖其观察者的行为。

我建议您重新考虑整个过程。您正在做的事情看起来比互动更互动。

答案 1 :(得分:0)

为了清晰起见,我将回声Paulo:

  • 可观察对象不关心观察者。当一个Observable将等待其同步Observer时,最好将其视为实现的偶然事件。一个Observable根本不会在异步Observer上等待。无论哪种方式,都不应依赖等待。

  • 您应该重新考虑自己的操作方式。您正在使用反应式库编写交互式代码。可能是工具选择错误或工具使用不当。

  • 您的代码中堆满了Rx code-smells。将反应式代码视为流程图。您的代码流程图看起来像意大利面条。它看起来应该更像一棵二叉树。

这听起来像是XY problem:我建议您用您要完成的工作来重新表达您的问题。