
Yan Cui
I help clients go faster for less using serverless technologies.
With the official release of .Net 4.5 and Visual Studio 2012, I suspect many .Net developers will be rushing to rewrite their data access or network layers (amongst many many other things!) to take advantage of the new async-await (see the excellent 101 examples here) language feature in C#, which means you’ll likely be working with the Task and Task<T> type an awful lot.
If you have F# code that needs to interop with C# that returns or awaits some task types then you’ve probably already come across the Async.StartAsTask<T> and Async.AwaitTask<T> methods for converting between F#’s Async<T> and Task<T> types. Curiously, there are no equivalent methods on the Async class for converting between Async<unit> and Task types.
So, to fill in the gaps ourselves, here are two simple functions to do just that:
open System.Threading.Tasks | |
[<AutoOpen>] | |
module Async = | |
let inline awaitPlainTask (task: Task) = | |
// rethrow exception from preceding task if it fauled | |
let continuation (t : Task) : unit = | |
match t.IsFaulted with | |
| true -> raise t.Exception | |
| arg -> () | |
task.ContinueWith continuation |> Async.AwaitTask | |
let inline startAsPlainTask (work : Async<unit>) = Task.Factory.StartNew(fun () -> work |> Async.RunSynchronously) | |
/// Usage | |
> let sleepy = async { | |
do! Async.Sleep(5000) // sleep for 5 seconds | |
printfn "awake" | |
};; | |
val sleepy : Async<unit> | |
sleepy |> Async.startAsPlainTask;; | |
val it : Task = System.Threading.Tasks.Task {AsyncState = null; | |
CreationOptions = None; | |
Exception = null; | |
Id = 2; | |
IsCanceled = false; | |
IsCompleted = false; | |
IsFaulted = false; | |
Status = Running;} | |
// 5 seconds later | |
> awake | |
> let sleepy2 = async { | |
do! sleepy |> Async.startAsPlainTask |> Async.awaitPlainTask | |
printfn "feeling sleepy again..." | |
};; | |
val sleepy2 : Async<unit> | |
> sleepy2 |> Async.Start;; | |
val it : unit = () | |
// 5 seconds later.. | |
> awake | |
feeling sleepy again... |
Enjoy!
Whenever you’re ready, here are 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
- I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
- Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.
As a Task is also a Task (https://msdn.microsoft.com/en-us/library/dd321424(v=vs.110).aspx), you can also just do:
`let StartAsPlainTask x = Async.StartAsTask x :> Task`