Планировщик по умолчанию для Range
имеет значение Scheduler.CurrentThread
.
CurrentThread
и Immediate
имеют поведение, которое иногда приводит к вечному батуту или тупику, особенно при попытке синхронного использования с Observable.Create
или аналогичные незапланированные холодные наблюдаемые.
Точные причины, по которым они блокируются, трудно описать, но они похожи на поведение здесь и здесь .
Observable.Create (fun (sub : IObserver<_>) ->
sub.OnNext(1)
sub.OnNext(2)
sub.OnNext(3)
d :> IDisposable //<-- this dispose should cancel all `OnNext`
)
Вышеуказанное распоряжение никогда не может быть вызвано, чтобы предотвратить выброс предметов - до после того, как предметы были выброшены. Если вы вручную создаете наблюдаемую, попробуйте заставить ее принять аргумент планировщика.
DispatcherScheduler
вернувшись в ядро Rx. Вот реализация минимального DispatcherScheduler
:
type DispatcherScheduler =
static member Instance = {
new IScheduler with
member _.Now = DateTimeOffset.Now
member _.Schedule<'S>(state: 'S, action: Func<IScheduler, 'S, IDisposable>) : IDisposable =
let op = Application.Current.Dispatcher.InvokeAsync(fun () -> action.Invoke(DispatcherScheduler.Instance, state))
Disposable.Create(fun () -> op.Abort() |> ignore)
member _.Schedule<'S>(state: 'S, dueTime: TimeSpan, action: Func<IScheduler, 'S, IDisposable>) : IDisposable = failwith "Not Impl"
member _.Schedule<'S>(state: 'S, dueTime: DateTimeOffset, action: Func<IScheduler, 'S, IDisposable>) : IDisposable = failwith "Not Impl"
}