Je voudrais bloquer l'exécution asynchrone jusqu'à ce que les utilisateurs appuient sur une touche de la console.
Voici ce que j'ai trouvé:
async {
printfn "%s" "Press any key... "
do! waitForAnyKey
printfn "%s" "You pressed a key. "
}
Utilisé comme ceci:
let waitForAnyKey = async {
do!
new Task (fun () ->
printfn "%s" "waiting for a key"
Console.ReadKey () |> ignore
printfn "%s" "got a key"
)
|> Async.AwaitTask
}
Cependant, le Tâche n'est jamais exécuté.
tâche pour cela entièrement? 3 Réponses :
Vous pouvez écrire waitForAnyKey sans les bits d'interopérabilité Task Async:
let waitForAnyKey = async {
do Console.ReadKey () |> ignore
}
Vous pouvez ensuite l'appeler à tout moment où vous souhaitez attendre l'entrée . Votre exemple d'utilisation fonctionnerait parfaitement avec cette implémentation.
Quelles sont les implications en termes de blocage des asynchrones enfants avec cette approche?
@sdgfsdh pouvez-vous expliquer davantage votre préoccupation, je pense que cette réponse est bonne.
Le constructeur Task crée une nouvelle tâche mais ne la démarre pas. Utiliser plutôt Task.Run résoudre le problème:
let waitForAnyKey = async {
do!
Task.Run (fun () ->
printfn "%s" "waiting for a key"
Console.ReadKey () |> ignore
printfn "%s" "got a key"
)
|> Async.AwaitTask
}
Console.ReadKey n'a actuellement pas d'équivalent qui renvoie une Task (ce qui m'a surpris), bien que l'idée a été suggéré.
Sans tâches, avec Async.FromContinuations
open System
let waitForAnyKey =
Async.FromContinuations (fun (cont, _, _) ->
printfn "%s" "waiting for a key"
cont (Console.ReadKey ())
printfn "%s" "got a key"
)
let test () =
async {
let! key = waitForAnyKey
printfn "%O" key.Key
}
|> Async.RunSynchronously
test ()