この質問は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
いつでもキャンセルできるように、2つの関数をどのように呼び出す必要がありますか?
流れは
- ユーザーが[更新]をクリックします
prepareModel
(1)開始され、非同期で実行されているため、UIは応答性が高く、ユーザーはアプリケーションを操作できます
- ユーザーがデータを変更し、[更新]をもう一度クリックします
prepareModel
(1)fromがキャンセルされ、newprepareModel
(2)が開始されます
- ユーザーがデータを変更し、[更新]をもう一度クリックします
prepareModel
(2)がキャンセルされ、新しいprepareModel
(3)が開始されます- ..
prepareModel
(n)終了updateUI
UIスレッドで実行され、UIを再描画します
(私の最初の解決策は、1つだけが実行されるMailboxProcessor
ことを保証することに基づいています。Async.TryCancelledはAsync.RunSynchronouslyでは機能しませんが、これを実験したので、バグはありません)prepareModel