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 ()