Created
April 12, 2019 06:29
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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