这个问题是基于Async.TryCancelled 不适用于 Async.RunSynchronously看起来很复杂,所以我将削减一个我尝试解决的简单部分。
假设我有这个功能:
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
准备应该显示给用户的数据。updateUI
刷新 UI(删除旧控件并根据新数据创建新 ctl)。
问题:我应该如何调用这两个函数以便可以prepareModel
随时取消?
流量是
- 用户点击刷新
prepareModel
(1) 异步启动和运行,因此 UI 是响应式的,用户可以使用应用程序
- 用户更改数据并再次单击刷新
prepareModel
(1) from 被取消,newprepareModel
(2) 开始
- 用户更改数据并再次单击刷新
prepareModel
(2) 被取消并prepareModel
开始新的 (3)- ..
prepareModel
(n) 完成updateUI
在 UI 线程上运行,重绘 UI
(我的第一个解决方案基于MailboxProcessor
确保只prepareModel
执行一个,请参阅Async.TryCancelled 不适用于 Async.RunSynchronously但当我对此进行试验时,它不是没有错误的)