Этот вопрос основан на 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
обновляет пользовательский интерфейс (удаляет старые элементы управления и создает новые ctls на основе новых данных).
Вопрос: Как мне вызвать две функции, чтобы prepareModel
можно было отменить в любое время?
Поток
- пользователь нажимает обновить
prepareModel
(1) запущен и работает асинхронно, поэтому пользовательский интерфейс отзывчив и пользователь может работать с приложением
- пользователь изменяет данные и нажимает кнопку обновить снова
prepareModel
(1) от отменяется и
новый prepareModel
(2) запущен
- пользователь изменяет данные и снова нажимает кнопку Обновить
prepareModel
(2) отменяется и
новый prepareModel
(3) запущен
- ..
prepareModel
(n) закончено
updateUI
запускается в потоке пользовательского интерфейса, перерисовывает пользовательский интерфейс
(Мое первое решение основано на MailboxProcessor
, которое обеспечивает выполнение только одного prepareModel
, см. Async.TryCancelled не работает с Async.RunSynchronously , но, как я экспериментировал с этим, это не без ошибок)