这个问题是基于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但当我对此进行试验时,它不是没有错误的)