Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O FSharp.Core 11 adiciona funções para interoperabilidade de tarefas, transformações de resultado e simultaneidade limitada. Use-os com fluxos de trabalho assíncronos e expressões de tarefa existentes; eles não exigem o protótipo assíncrono de runtime.
Aguardar operações de .NET da assíncrona
Para iniciar uma operação de .NET com o token de cancelamento do fluxo de trabalho assíncrono, passe uma fábrica paraAsync.StartTaskImmediate:
open System.IO
let tryReadFile path =
async {
try
let! contents =
Async.StartTaskImmediate(fun ct -> File.ReadAllTextAsync(path, ct))
return Some contents
with :? FileNotFoundException ->
return None
}
A leitura do arquivo recebe o token de cancelamento do fluxo de trabalho. Um arquivo ausente retorna None; uma leitura bem-sucedida retorna Some contents. O fluxo de trabalho aguarda a conclusão, incluindo cancelamento e limpeza.
Use Async.Await quando você já tiver um valor semelhante a uma tarefa. Ambas as APIs propagam diretamente a única exceção subjacente de uma tarefa com falha. Uma agregação com várias exceções internas permanece uma agregação.
Async.AwaitTask mantém seu comportamento de encapsulamento de exceção existente.
| API | Formas de argumento/resultado com suporte |
|---|---|
Async.Await |
Task<'T> -> Async<'T>; Task -> Async<unit> |
Async.Await |
ValueTask<'T> -> Async<'T>; ValueTask -> Async<unit> |
Async.Await |
Sobrecarga embutida como tarefa usando o GetAwaiter protocolo. |
Async.StartTaskImmediate |
(CancellationToken -> Task<'T>) -> Async<'T>; retornos não genéricos TaskAsync<unit>. |
Async.StartTaskImmediate |
ValueTask<'T>Sobrecargas de fábrica correspondentes ValueTaske semelhantes a tarefas. |
Task.startAsyncImmediate |
CancellationToken -> Async<'T> -> Task<'T> |
Async.RunSynchronouslyImmediate |
Async<'T> * ?cancellationToken: CancellationToken -> 'T |
Async.RunSynchronouslyImmediate começa no thread de chamada, ao contrário Async.RunSynchronously de um thread em primeiro plano e bloqueia a conclusão. Ele não tem parâmetro de tempo limite. Prefira a composição assíncrona nos threads de interface do usuário e solicitação.
Expor um fluxo de trabalho assíncrono como uma tarefa
Para oferecer o fluxo de trabalho de leitura de arquivo acima para chamadores baseados em tarefas, aceite um token de cancelamento e passe-o:Task.startAsyncImmediate
let tryReadFileTask (path: string) (ct: CancellationToken) =
tryReadFile path |> Task.startAsyncImmediate ct
A ponte retorna Task<string option> e propaga o cancelamento. Ele começa no thread de chamada até a primeira suspensão; continuações posteriores não precisam usar esse thread.
Simultaneidade associada
Um Async<'T> valor descreve o trabalho adiado. Uma tarefa geralmente representa uma operação que já foi iniciada. Para limitar o uso de recursos, descreva o trabalho da tarefa como fábricas em vez de tarefas já em execução:
open System.IO
open System.Threading
let readFiles (paths: seq<string>) (ct: CancellationToken) =
paths
|> Seq.map (fun path ->
fun token -> File.ReadAllTextAsync(path, token))
|> Task.parallelLimit 4 ct
Task.parallelLimit inicia no máximo o limite positivo de cálculos simultaneamente e retorna resultados na ordem de entrada. A ordem de início e a ordem de conclusão não são especificadas. Para simultaneidade maior que uma, cada fábrica recebe um token vinculado que também sinaliza falha entre irmãos; para execução sequencial, ele recebe o token fornecido diretamente.
Quando uma falha de computação é solicitada, o cancelamento é solicitado para seus irmãos. As operações devem observar seus tokens para cooperar. Se vários cálculos falharem, uma exceção será propagada; não depende de qual falha ganha.
| Function | Forma da assinatura |
|---|---|
Task.parallelLimit |
int -> CancellationToken -> seq<CancellationToken -> Task<'T>> -> Task<'T[]> |
Task.parallelDoLimit |
int -> CancellationToken -> seq<CancellationToken -> Task<unit>> -> Task<unit> |
Task.sequential |
CancellationToken -> seq<CancellationToken -> Task<'T>> -> Task<'T[]> |
Task.sequentialDo |
CancellationToken -> seq<CancellationToken -> Task<unit>> -> Task<unit> |
Async.parallelLimit |
int -> seq<Async<'T>> -> Async<'T[]> |
Async.parallelDoLimit |
int -> seq<Async<unit>> -> Async<unit> |
Async.sequentialDo |
seq<Async<unit>> -> Async<unit> |
As Async funções fluem o token de cancelamento ambiente do fluxo de trabalho. Existente Async.Parallel (incluindo sua opção de limite de simultaneidade) e Async.Sequential permanecer disponível. As Do variantes expõem um unit resultado quando você só precisa de conclusão. Um limite de simultaneidade não é um limitador de taxa: operações rápidas ainda podem produzir muitas solicitações por segundo.
Transformar resultados e recuperar-se de falhas
Os Microsoft.FSharp.Control.Asyncmódulos e ValueTask os módulos Taskexpõem essas funções qualificadas.
M<'T> na coluna de forma significa o tipo de computação correspondente, não uma abreviação de tipo F#.
| Funções qualificadas | Forma |
|---|---|
Async.result, Task.result, ValueTask.result |
'T -> M<'T> |
Async.map, Task.map, ValueTask.map |
('T -> 'U) -> M<'T> -> M<'U> |
Async.bind, Task.bind, ValueTask.bind |
('T -> M<'U>) -> M<'T> -> M<'U> |
Async.ignore<'T>, Task.ignore<'T>, ValueTask.ignore<'T> |
M<'T> -> M<unit>; argumento de tipo de entrada explícito necessário. |
Async.catchWith, Task.catchWith, ValueTask.catchWith |
(exn -> 'T) -> M<'T> -> M<'T> |
Async.catch, Task.catch, ValueTask.catch |
M<'T> -> M<Result<'T, exn>> |
Async.empty, Task.empty, ValueTask.empty |
M<unit> |
Task.ofValueTask |
ValueTask<'T> -> Task<'T> |
ValueTask.ofTask |
Task<'T> -> ValueTask<'T> |
Por exemplo, mapeie o conteúdo de um arquivo para um comprimento e, em seguida, represente uma falha de leitura como um Result:
open System.IO
open System.Threading
let fileLength (path: string) (ct: CancellationToken) =
File.ReadAllTextAsync(path, ct)
|> Task.map String.length
|> Task.catch
Um arquivo que contém Report 1 fornece Ok 8. Um arquivo ausente fornece um ErrorFileNotFoundException. Para descartar um valor bem-sucedido em vez de transformá-lo, especifique o tipo de entrada ao chamar ignore:
let completion: System.Threading.Tasks.Task<unit> =
Task.result 42 |> Task.ignore<int>
catchWith fornece um valor de substituição para uma falha de não cancelamento; ele não executa outra computação assíncrona.
catch retorna Ok ou Error. O cancelamento não é convertido em um valor de erro ou passado para o manipulador de recuperação.
Task.empty é um Task<unit>, não o não genérico Task.CompletedTask.
Ao contrário de minúsculas, os retornos existentes Async.catchAsync.CatchChoice. A recuperação lida com falhas da computação fornecida, não exceções síncronas geradas antes da chamada. Assíncrono permanece adiado; as tarefas permanecem ansiosas.
Disponibilidade de ValueTask e biblioteca
As APIs ValueTask exigem o build ou net10.0 o netstandard2.1 build do FSharp.Core 11. Consulte a seleção de destino do Core.
Observe o contrato de consumo único do ValueTask: consuma cada valor uma vez, não por meio de esperas ou pipelines separados. Para esperas repetidas, chame Task.ofValueTask uma vez e reutilize apenas a tarefa resultante.