Interop with .NET TPL
TPL : Task Parallel Library
Interaction with .NET libraries
Asynchronous libraries in .NET and the async/await Cβ― pattern:
β Based on TPL and the Task type
Gateways with asynchronous workflow Fβ― :
Async.AwaitTaskandAsync.StartAsTaskfunctionstask {}block
Gateway functions
Async.AwaitTask: Task<'T> -> Async<'T>
β Consume an asynchronous .NET library in async block
Async.StartAsTask: Async<'T> -> Task<'T>
β Launch an async calculation as a Task
let getValueFromLibrary param = async {
let! value = DotNetLibrary.GetValueAsync param |> Async.AwaitTask
return value
}
let computationForCaller param =
async {
let! result = getAsyncResult param
return result
}
|> Async.StartAsTasktask {} block
task {} blockAllows consuming an asynchronous .NET library directly, using a single
Async.AwaitTaskrather than one for each async method called.
π‘ Available since Fβ― 6 (before, we needed the Ply NuGet package)
Async vs Task
Async vs Task1. Calculation start mode
Task = hot tasks β calculations started immediatelyβ
Async = task generators = calculation specification, independent of startup
β Functional approach: no side-effects or mutations, composability
β Control of startup mode: when and how π
2. Cancellation support
Task: by adding a CancellationToken parameter to async methods
β Forces manual testing if token is canceled = tedious + error-proneβ
Async: automatic support in calculations - token to be provided at startup π
Recommendation for async functions in Fβ―
Cβ― async applied at a method level
β Fβ― async defines an async block, not an async function
β Recommendation:
Β» Put the entire body of the async function in an async block.
Pitfalls of the async/await Cβ― pattern
async/await Cβ― patternPitfall 1 - Really asynchronous?
In Cβ―: method async remains on the calling thread until the first await
β Misleading feeling of being asynchronous throughout the method
Pitfall 2 - Omit the await
awaitCompiles but returns unexpected result: After before Beforeβ
This pitfall is also present in Fβ―:
Compiles but returns another unexpected result: no Before at all βοΈ
Compilation warnings
The previous examples compile but with big warnings!
Cβ― warning CS4014 message:
Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the
awaitoperator...
Fβ― warning FS0020 message:
The result of this expression has type
Async<unit>and is implicitly ignored. Consider usingignoreto discard this value explicitly...
β Recommendation: be sure to always handle this type of warnings! This is even more crucial in Fβ― where compilation can be tricky.
Async.Parallel
Thread-safety
Impure functions can be not thread-safe, for instance if they mutate a shared object like the Console.
It's possible to make them thread-safe using the lock function:
Results in the console (example):

Last updated
Was this helpful?