Почему `CurrentThreadScheduler` запускается сразу во внешней области? - PullRequest
0 голосов
/ 01 апреля 2020
open System.Reactive.Concurrency
open System.Reactive.Disposables
open System

let print i = printfn "%i on thread %i" i Threading.Thread.CurrentThread.ManagedThreadId
CurrentThreadScheduler.Instance.Schedule((), fun _ _ ->
    CurrentThreadScheduler.Instance.Schedule((), fun _ _ -> print 3)
    print 2
    Disposable.Empty
    )

print 1

Вывод:

2 on thread 1
3 on thread 1
1 on thread 1

Почему print 1 выполняется последним, когда он находится во внешней области видимости? Почему предшествующий ему оператор не ставится в очередь и сразу же выполняется в отличие от CurrentThreadScheduler.Instance.Schedule((), fun _ _ -> print 3)?

1 Ответ

2 голосов
/ 01 апреля 2020

CurrentThreadScheduler будет:

  1. Запустить thunk немедленно
  2. Если thunk запланирован на t секунд позже, он будет спать в течение t секунд
  3. Если канал уже запущен, он будет добавлен в очередь.

Следуя этим 3 правилам:

  1. Первый запланированный элемент запускается немедленно ( print 2)
  2. Первый элемент все еще работает, пока второй запланирован, поэтому он ставится в очередь
  3. Первый элемент завершается, отключается, второй элемент запускается (печать 3)
  4. Планировщик завершил блокировку, поэтому выполняется последняя строка (печать 1)

См. Реализация CurrentThreadScheduler .

ImmediateScheduler, напротив, просто "запустить" сразу же ".

...