Skip to content

Instantly share code, notes, and snippets.

@rastreus
Created April 12, 2019 06:29
Show Gist options
  • Save rastreus/f88cd47f8708f93b7c4fe276ac1dd7f3 to your computer and use it in GitHub Desktop.
Save rastreus/f88cd47f8708f93b7c4fe276ac1dd7f3 to your computer and use it in GitHub Desktop.
This is an example of using CancellationTokenSource with Fabulous--the Xamarin.Forms Elmish framework.
namespace FabTestCTS
open System.Diagnostics
open Fabulous.Core
open Fabulous.DynamicViews
open Xamarin.Forms
module Cmd =
let ofAsyncMsgOption (p: Async<'msg option>) : Cmd<'msg> =
[ fun dispatch -> async { let! msg = p in match msg with None -> () | Some msg -> dispatch msg } |> Async.StartImmediate ]
module App =
type Model =
{ Test : string }
type Msg =
| Start
| Cancel
let initModel =
{ Test = "test" }
let init () =
initModel, Cmd.none
let mutable cts = new System.Threading.CancellationTokenSource()
let work =
async {
while true do
printfn "Working..."
do! Async.Sleep 1000
}
let start = async {
cts.Cancel()
cts <- new System.Threading.CancellationTokenSource()
printfn "Start"
Async.StartImmediate(work, cts.Token)
return None
}
let cancel = async {
printfn "Cancel"
cts.Cancel()
return None
}
let update msg model =
match msg with
| Start -> model, Cmd.ofAsyncMsgOption start
| Cancel -> model, Cmd.ofAsyncMsgOption cancel
let view (model: Model) dispatch =
View.ContentPage(
content = View.StackLayout(padding = 20.0, verticalOptions = LayoutOptions.Center,
children = [
View.Button(text = "Start", command = (fun () -> dispatch Start), horizontalOptions = LayoutOptions.Center)
View.Button(text = "Cancel", command = (fun () -> dispatch Cancel), horizontalOptions = LayoutOptions.Center)
]))
// Note, this declaration is needed if you enable LiveUpdate
let program = Program.mkProgram init update view
type App () as app =
inherit Application ()
let runner =
App.program
#if DEBUG
|> Program.withConsoleTrace
#endif
|> Program.runWithDynamicView app
#if DEBUG
// Uncomment this line to enable live update in debug mode.
// See https://fsprojects.github.io/Fabulous/tools.html for further instructions.
//
//do runner.EnableLiveUpdate()
#endif
// Uncomment this code to save the application state to app.Properties using Newtonsoft.Json
// See https://fsprojects.github.io/Fabulous/models.html for further instructions.
#if APPSAVE
let modelId = "model"
override __.OnSleep() =
let json = Newtonsoft.Json.JsonConvert.SerializeObject(runner.CurrentModel)
Console.WriteLine("OnSleep: saving model into app.Properties, json = {0}", json)
app.Properties.[modelId] <- json
override __.OnResume() =
Console.WriteLine "OnResume: checking for model in app.Properties"
try
match app.Properties.TryGetValue modelId with
| true, (:? string as json) ->
Console.WriteLine("OnResume: restoring model from app.Properties, json = {0}", json)
let model = Newtonsoft.Json.JsonConvert.DeserializeObject<App.Model>(json)
Console.WriteLine("OnResume: restoring model from app.Properties, model = {0}", (sprintf "%0A" model))
runner.SetCurrentModel (model, Cmd.none)
| _ -> ()
with ex ->
App.program.onError("Error while restoring model found in app.Properties", ex)
override this.OnStart() =
Console.WriteLine "OnStart: using same logic as OnResume()"
this.OnResume()
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment