Skip to content

Latest commit

 

History

History
63 lines (45 loc) · 2.07 KB

README.md

File metadata and controls

63 lines (45 loc) · 2.07 KB

SchedulerSynchronizationContext

A synchronization context which schedules work to a given scheduler, and an implementation of Async.SwitchToScheduler which uses it.

For example, if you have some work which you want performed on a background scheduler to avoid blocking the UI thread, and the value propagated to the UI thread, this can be done as follows:

open SchedulerSynchronizationContext

let asyncWork uiScheduler backgroundScheduler =
    async {
        do! Async.SwitchToScheduler backgroundScheduler
        let backgroundResult = backgroundWork ()

        do! Async.SwitchToScheduler uiScheduler
        return uiWork backgroundResult
    }

This can then be used as follows (I've used EventLoopSchedulers which name their threads to clarify which thread work is performed on):

#r @"..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll"
#r @"..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll"
#r @"..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll"
#r @"..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll"
#r @"bin\Debug\SchedulerSynchronizationContext.dll"

open System.Threading
open System.Reactive.Concurrency

open SchedulerSynchronizationContext

let backgroundWork () =
    sprintf "backgroundWork ran on %s" Thread.CurrentThread.Name

let uiWork x =
    sprintf "%s\nuiWork ran on %s" x Thread.CurrentThread.Name

let asyncWork uiScheduler backgroundScheduler =
    async {
        do! Async.SwitchToScheduler backgroundScheduler
        let backgroundResult = backgroundWork ()

        do! Async.SwitchToScheduler uiScheduler
        return uiWork backgroundResult
    }

let uiScheduler         = new EventLoopScheduler(fun x -> new Thread(x, Name = "UI scheduler"))
let backgroundScheduler = new EventLoopScheduler(fun x -> new Thread(x, Name = "Background scheduler"))

let t = asyncWork uiScheduler backgroundScheduler |> Async.StartAsTask
printfn "Result:\n\n%s" t.Result

This will output:

Result:

backgroundWork ran on Background scheduler
uiWork ran on UI scheduler