This question is based on Async.TryCancelled doesn't work with Async.RunSynchronously that looks complex, so I will cut a simple part that I try to solve.
Suppose I have this functions:
let prepareModel () =
async {
// this might take a lot of time (1-50seconds)
let! a = ...
let! b = ...
let! res = combine a b
return res
}
let updateUI model =
runOnUIThread model
prepareModel
prepares data that should be displayed to the user. updateUI
refreshes the UI (removes old controls and creates new ctls based on new data).
Question: How should I call the two functions so that prepareModel
is cancellable any time?
The flow is
- user clicks refresh
prepareModel
(1) started and is running asynchronously, so the UI is responsive and user can work with the application
- user changes data and clicks refresh again
prepareModel
(1) from is cancelled and newprepareModel
(2) is started
- user changes data and clicks refresh again
prepareModel
(2) is cancelled and newprepareModel
(3) is started- ..
prepareModel
(n) finishedupdateUI
is ran on UI thread, redraws the UI
(My first solution is based on MailboxProcessor
that ensures that only one prepareModel
is executed, see at Async.TryCancelled doesn't work with Async.RunSynchronously but as I experimented with this, it's not bug free)
One possible approach would be to start the workflow asynchronously in the background using
Async.Start
(then it should be cancellable). To redraw the UI at the end, you can useAsync.SwitchToContext
to make sure that the last part of the workflow executes on the UI. Here is a sketch: