Самый простой вариант - использовать Async.StartChild
.Этот примитив запускает асинхронную операцию в фоновом режиме (в пуле потоков) и возвращает «токен», который можно использовать для ожидания завершения операции.Это не блокирует рабочий процесс, поэтому вы можете продолжить выполнение других операций:
let productOfIncrements x y =
async {
// Start the 'incr x' operation in background
let! x1Op = async {return incr x} |> Async.StartChild
// Continue doing other work
// (synchronously since it takes the same time as the above.)
let y1 = incr y
// Now wait for the result of 'incr x' (if it is still running)
let! x1 = x1Op
// return the product (just call the function synchronously)
return product x1 y1
}
Если две операции возвращают один и тот же тип, то вы также можете использовать Async.Parallel
, который состоит из нескольких операций для запускапараллельно.
Если вы работаете с вычислениями, которые связаны исключительно с ЦП, и вам необходимо создать большое их количество, то вы также можете напрямую использовать .NET Tasks
(см., например, thisстатья ).Задачи более эффективны, но не так элегантны в использовании (и не поддерживают красиво асинхронное ожидание).
В качестве дополнительного примечания обычно используется термин pipe в мире F # или .NET) для более сложной вещи - например, скажем, у вас есть ряд шагов, которые зависят друг от друга.При обработке нескольких входов вы можете выполнять шаги параллельно (и при этом ограничивать общий паралеллизм).Это также можно сделать с помощью асинхронных рабочих процессов F # - см. , например, эту статью .Существует также каркас с именованными конвейерами , который реализует эту концепцию.