Асинхронное ожидание ключа в F #? - PullRequest
2 голосов
/ 31 мая 2019

Я хотел бы заблокировать асинхронное выполнение, пока пользователи не нажмут любую клавишу в консоли.

Вот что я придумала:

let waitForAnyKey = async {
  do!
    new Task (fun () ->
      printfn "%s" "waiting for a key"
      Console.ReadKey () |> ignore
      printfn "%s" "got a key"
    )
    |> Async.AwaitTask
}

Используется так:

async {
  printfn "%s" "Press any key... "
  do! waitForAnyKey
  printfn "%s" "You pressed a key. "
}

Однако Task никогда не запускается.

  • Как мне написать это на F #?
  • Могу ли я избежать создания Task для этого целиком?

Ответы [ 3 ]

2 голосов
/ 31 мая 2019

Без заданий, с 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 ()
1 голос
/ 31 мая 2019

Вы можете написать waitForAnyKey без битов асинхронного взаимодействия Задания <->:


let waitForAnyKey = async {
  do Console.ReadKey () |> ignore
}

Вы можете вызывать его в любое время, когда захотите дождаться ввода.Ваш пример использования будет отлично работать с этой реализацией.

0 голосов
/ 31 мая 2019

Конструктор Task создает новую задачу, но не запускает ее. Использование Task.Run вместо этого должно решить проблему:

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 в настоящее время не имеет эквивалента, который возвращает задачу (что меня удивило), хотя была предложена идея .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...