1

次の定義を検討してください

let test =
    Async.FromContinuations(
        fun (cont,econt,ccont) ->
            let rec inner () =
                async {
                    do printfn "looping..."
                    do! Async.Sleep 1000
                    return! inner ()
                }

            Async.Start(inner ())
            cont ())

そのように計算を試したいとします

let cts = new CancellationTokenSource ()
Async.Start(test, cts.Token)
cts.Cancel()

適切なキャンセル トークンを渡していないため、当然、内側のループは停止しません。Async.FromContinuations を通じて外部キャンセル トークンを取得する方法はありますか? async ビルダーと Async.CancellationToken を使用してこれを書き直すことはできますが、そうすると内部式に継続を渡すことができなくなります。

4

2 に答える 2

2

このようなsmth?

let test =
    async {
        let! ct = Async.CancellationToken
        return! Async.FromContinuations(
            fun (cont,econt,ccont) ->
                let rec inner () =
                    async {
                        do printfn "looping..."
                        do! Async.Sleep 1000
                        return! inner ()
                    }

                Async.Start(inner (), cancellationToken = ct)
                cont ())
    }
let cts = new CancellationTokenSource ()
Async.Start(test, cts.Token)
cts.CancelAfter(1000)
于 2012-09-20T22:53:16.093 に答える
2

何をしようとしているのか説明していただけますか?コードを正しく理解している場合は、innerループ関数をバックグラウンドで開始してから、並行して残りのワークフローを実行し続けます(cont()呼び出しを使用)。

これを行うには、は必要ありませんAsync.FromContinuationsこれを正確に実行する関数があり、例外、キャンセルトークンなどの処理も​​処理します。

私はあなたがこのようにあなたのプログラムを書き直すことができると思います:

let test = 
    // The inner loop function from your example
    let rec inner () = async { 
        do printfn "looping..." 
        do! Async.Sleep 1000 
        return! inner ()  } 

    async { 
      // Start the inner loop as a child async 
      let! _ = Async.StartChild(inner())
      // ... continue doing other things in parllel if you wish
      do printfn "main body running..." }

計算の開始とキャンセルは以前と同じように見えます。

let cts = new CancellationTokenSource () 
Async.Start(test, cts.Token) 
// This will cancel the 'inner' loop as well
cts.Cancel() 

Async.StartChildusingを呼び出すとlet!、内部タスクが開始され、キャンセルトークンなどが渡されます。後で子タスクが完了するまで待機するために使用できるトークンが返されますが、それを行わないため、_パターンを使用しました。

于 2012-09-21T10:41:37.653 に答える