비동기 및 작업 함수

FSharp.Core 11은 작업 interop, 결과 변환 및 제한된 동시성에 대한 함수를 추가합니다. 기존 비동기 워크플로 및 작업 식과 함께 사용합니다. 런타임 비동기 프로토타입은 필요하지 않습니다.

비동기에서 .NET 작업 대기

비동기 워크플로의 취소 토큰으로 .NET 작업을 시작하려면 팩터리를 다음으로 전달합니다Async.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
    }

파일 읽기는 워크플로의 취소 토큰을 받습니다. 누락된 파일이 반환 None됩니다. 읽기가 성공하면 반환됩니다 Some contents. 워크플로는 취소 및 정리를 포함하여 완료될 때까지 기다립니다.

작업과 유사한 값이 이미 있는 경우 사용합니다 Async.Await . 두 API 모두 오류가 발생한 작업의 단일 기본 예외를 직접 전파합니다. 여러 내부 예외가 있는 집계는 집계로 유지됩니다. Async.AwaitTask 는 기존 예외 래핑 동작을 유지합니다.

API 지원되는 인수/결과 셰이프
Async.Await Task<'T> -> Async<'T>; Task -> Async<unit>
Async.Await ValueTask<'T> -> Async<'T>; ValueTask -> Async<unit>
Async.Await 프로토콜을 사용하는 인라인 작업과 유사한 오버로드입니다 GetAwaiter .
Async.StartTaskImmediate (CancellationToken -> Task<'T>) -> Async<'T>; 제네릭 Task 이 아닌 반환 Async<unit>.
Async.StartTaskImmediate 해당 ValueTask, ValueTask<'T>및 작업과 유사한 팩터리 오버로드입니다.
Task.startAsyncImmediate CancellationToken -> Async<'T> -> Task<'T>
Async.RunSynchronouslyImmediate Async<'T> * ?cancellationToken: CancellationToken -> 'T

Async.RunSynchronouslyImmediate 는 포그라운드 스레드와 달리 Async.RunSynchronously 호출 스레드에서 시작하고 완료를 위해 차단합니다. 시간 제한 매개 변수가 없습니다. UI 및 요청 스레드에서 비동기 컴퍼지션을 선호합니다.

비동기 워크플로를 작업으로 노출

위의 파일 읽기 워크플로를 작업 기반 호출자에게 제공하려면 취소 토큰을 수락하고 다음을 통과 Task.startAsyncImmediate합니다.

let tryReadFileTask (path: string) (ct: CancellationToken) =
    tryReadFile path |> Task.startAsyncImmediate ct

브리지가 취소를 반환 Task<string option> 하고 전파합니다. 첫 번째 일시 중단까지 호출 스레드에서 시작됩니다. 이후 연속 작업에서는 해당 스레드를 사용할 필요가 없습니다.

바인딩된 동시성

값은 Async<'T> 지연된 작업을 설명합니다. 일반적으로 작업은 이미 시작된 작업을 나타냅니다. 리소스 사용을 제한하려면 작업 작업을 이미 실행 중인 작업이 아닌 팩터리로 설명합니다.

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 는 계산의 최대 양수 제한을 동시에 시작하고 입력 순서로 결과를 반환합니다. 시작 순서 및 완료 순서는 지정되지 않습니다. 1보다 큰 동시성의 경우 각 팩터리는 형제 실패를 알리는 연결된 토큰을 받습니다. 순차적 실행을 위해 제공된 토큰을 직접 받습니다.

하나의 계산 오류가 발생하면 해당 형제에 대해 취소가 요청됩니다. 작업에서 협력하려면 해당 토큰을 관찰해야 합니다. 여러 계산이 실패하면 한 가지 예외가 전파됩니다. 은 어떤 실패가 이기느냐에 따라 달라지지 않습니다.

Function 서명 셰이프
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>

함수는 Async 워크플로의 앰비언트 취소 토큰을 전달합니다. 기존 Async.Parallel (동시성 제한 옵션 포함)이며 Async.Sequential 계속 사용할 수 있습니다. 변형은 Do 완료만 필요한 경우 결과를 노출 unit 합니다. 동시성 제한은 속도 제한자가 아닙니다. 빠른 작업은 여전히 초당 많은 요청을 생성할 수 있습니다.

결과 변환 및 오류 복구

및 TaskValueTask 모듈은 Microsoft.FSharp.Control.Async이러한 정규화된 함수를 노출합니다. M<'T> 도형 열은 F# 형식 약어가 아닌 해당 계산 형식을 의미합니다.

정규화된 함수 Shape
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>; 명시적 입력 형식 인수가 필요합니다.
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>

예를 들어 파일의 내용을 길이에 매핑한 다음 읽기 실패를 다음과 같이 Result나타냅니다.

open System.IO
open System.Threading

let fileLength (path: string) (ct: CancellationToken) =
    File.ReadAllTextAsync(path, ct)
    |> Task.map String.length
    |> Task.catch

이 포함된 Report 1 파일은 을 제공합니다.Ok 8 누락된 파일은 Error 포함하는 FileNotFoundException파일을 제공합니다. 변환하지 않고 성공한 값을 취소하려면 다음을 호출 ignore할 때 입력 형식을 지정합니다.

let completion: System.Threading.Tasks.Task<unit> =
    Task.result 42 |> Task.ignore<int>

catchWith 는 취소되지 않은 오류에 대한 대체 값을 제공합니다. 다른 비동기 계산을 실행하지 않습니다. catch 반환 Ok 또는 Error. 취소가 오류 값으로 변환되거나 복구 처리기에 전달되지 않습니다. 가 제네릭이 아닌 /a0>입니다.

소문자 Async.catch에서와 달리 기존 Async.Catch 반환 합니다 Choice. 복구는 호출 전에 throw된 동기 예외가 아니라 제공된 계산의 오류를 처리합니다. 비동기 기능은 지연된 상태로 유지됩니다. 작업은 계속 열망합니다.

ValueTask 및 라이브러리 가용성

ValueTask API에는 FSharp.Core 11의 빌드 또는 net10.0 빌드가 필요합니다netstandard2.1. 핵심 대상 선택 항목을 참조하세요.

ValueTask 단일 사용 계약을 관찰합니다. 각 값은 별도의 awaits 또는 파이프라인을 통하지 않고 한 번 사용합니다. 반복 대기의 경우 한 번 호출 Task.ofValueTask 하고 결과 작업만 다시 사용합니다.

또한, 다음을 참조하세요.