Rx: CurrentThreadScheduler和immediatesscheduler的区别

本文关键字:区别 immediatesscheduler CurrentThreadScheduler Rx | 更新日期: 2023-09-27 18:14:19

谁能描述一下currentThreadScheduler和immediatesscheduler之间的区别?对于下面的代码,我看不出有什么不同。

        var rates = new List<FxRates>()
        {
            new FxRates() {CurrencyPair = "USD/GBP", BidPrice = 2.01m, AskPrice = 2.00m},
            new FxRates() {CurrencyPair = "USD/Eur", BidPrice = 1.3m, AskPrice = 1.31m},
            new FxRates() {CurrencyPair = "GBP/Eur", BidPrice = .8m, AskPrice = .81m}
        };
        var observable = rates.ToObservable(ImmediateScheduler.Instance);//Change to CurrentThreadScheduler
        observable.Subscribe(
            rate => Console.WriteLine("ThreadId:{0}, IsBackground:{1}, CurrencyPair:{2}",
                Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsBackground, rate.CurrencyPair));

Rx: CurrentThreadScheduler和immediatesscheduler的区别

前几天有人问我这个问题,这促使我想出一个简单的例子。考虑下面的代码,它调度一个动作:

  • 调度另一个动作将2写入控制台
  • 1写入控制台。

代码如下:

var scheduler = Scheduler.CurrentThread;
scheduler.Schedule(() => {
    scheduler.Schedule(() => Console.WriteLine(2));
    Console.WriteLine(1);
});

那么输出是什么呢?对于Scheduler.CurrentThread,我们得到:

1
2

但是如果我们交换Scheduler.Immediate,我们得到:

2
1

为什么?那么ImmediateScheduler将在当前线程上执行调度操作,只要它被调度。在这种情况下,我们看到,即使我们正在执行一个计划的操作,ImmediateScheduler将直接调用到新计划的操作。

相比之下,CurrentThreadScheduler将在当前线程上将操作排队,并在当前执行的操作完成时执行(如果有任何其他排队操作,则在任何其他排队操作之后)。

CurrentThreadScheduler在避免死锁方面特别有用,因为在任何给定时间只执行一个计划操作,从而避免了ImmediateScheduler的嵌套效果。出于同样的原因,它还避免了构建深度堆栈。

使用immerdiatesscheduler,操作立即执行。使用CurrentThreadScheduler,它将在当前线程上执行,但可能稍后执行:该操作被添加到队列中。

CurrentThreadScheduler vs immediatesscheduler