从非阻塞块调用阻塞代码时,了解控制流程?

时间:2012-01-21 18:46:38

标签: c# asynchronous system.reactive reactive-programming

我有以下代码

 static void Main(string[] args)
        {
            //var source = BlockingMethod();
            var source2 = NonBlocking();
            source2.Subscribe(Console.WriteLine);
            //source.Subscribe(Console.WriteLine);
            Console.ReadLine();

        }
            private static IObservable<string> BlockingMethod()
            {
              var subject = new ReplaySubject<string>();
              subject.OnNext("a");
              subject.OnNext("b");
              subject.OnCompleted();
              Thread.Sleep(1000);
              return subject;
            }
            private static IObservable<string> NonBlocking()
            {
                return Observable.Create<string>(
                    observable =>
                        {
                            observable.OnNext("c");
                            observable.OnNext("d");
                            observable.OnCompleted();
                            //Thread.Sleep(1000);

                            var source = BlockingMethod();
                            source.Subscribe(Console.WriteLine);

                            return Disposable.Create(() => Console.WriteLine("Observer has unsubscribed"));
                            //or can return an Action like
                            //return () => Console.WriteLine("Observer has unsubscribed");
                        });
            }
        }

打印

c
d
Observer has unsubscribed
a
b

任何人都可以帮助我获得程序中的控制流程。我确实尝试过阅读Call Stack等。但是无法理解所有内容。

修改 为什么我得到上面的输出(我认为是正确的)而不是

 c 
 d 
 a 
 b 
 Observer has unsubscribed

1 个答案:

答案 0 :(得分:2)

预期行为和实际行为的差异来自以下行:

var subject = new ReplaySubject<string>();

默认情况下,ReplaySubject使用Scheduler.CurrentThread。就好像你这样声明:

var subject = new ReplaySubject<string>(Scheduler.CurrentThread);

使用当前线程进行调度时,您的操作会排队等待 - 等待当前正在执行的代码在启动之前完成。如果您希望代码立即运行,则需要使用Scheduler.Immediate,如下所示:

var subject = new ReplaySubject<string>(Scheduler.Immediate);

这是否足以解释它?