Может ли кто-нибудь описать разницу между currentThreadScheduler и ImmediateScheduler? Для приведенного ниже кода я не вижу никакой разницы, которую он делает?
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));
С помощью ImmerdiateScheduler действие выполняется немедленно. С CurrentThreadScheduler он будет выполняться в текущем потоке, но может быть выполнен позже: действие добавляется в очередь.
Кто-то спросил меня об этом на днях, и это побудило меня привести простой пример. Рассмотрим следующий код, который планирует действие, которое:
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
очередь действие в текущем потоке и будет выполнено, когда текущее выполняемое действие завершится (и после любых других действий в очереди, если они есть).
CurrentThreadScheduler
может быть особенно полезен во избежание взаимоблокировок, поскольку в любой момент времени будет выполняться только одно запланированное действие, избегая эффекта вложенности ImmediateScheduler
. Кроме того, он также избегает создания глубоких стеков.