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