Skip to content

Instantly share code, notes, and snippets.

@thinkbeforecoding
Created April 27, 2015 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thinkbeforecoding/f23652200b85300d36a8 to your computer and use it in GitHub Desktop.
Save thinkbeforecoding/f23652200b85300d36a8 to your computer and use it in GitHub Desktop.
Async
[<AutoOpen>]
module Async
// Async extension to enable the direct use of Task<T> and Task
// in async {} blocs
open System
open System.Threading.Tasks
type Microsoft.FSharp.Control.Async with
static member AsyncRaise (e : #exn) =
Async.FromContinuations(fun (_,econt,_) -> econt e)
static member AwaitTask (t : Task) =
let flattenExns (e : AggregateException) = e.Flatten().InnerExceptions |> Seq.nth 0
let rewrapAsyncExn (it : Async<unit>) =
async { try do! it with :? AggregateException as ae -> do! Async.AsyncRaise(flattenExns ae) }
let tcs = new TaskCompletionSource<unit>(TaskCreationOptions.None)
t.ContinueWith((fun t' ->
if t.IsFaulted then tcs.SetException(t.Exception |> flattenExns)
elif t.IsCanceled then tcs.SetCanceled ()
else tcs.SetResult(())), TaskContinuationOptions.ExecuteSynchronously)
|> ignore
tcs.Task |> Async.AwaitTask |> rewrapAsyncExn
type Microsoft.FSharp.Control.AsyncBuilder with
member this.Bind(t: Task<'a>, f: 'a -> Async<'b>) : Async<'b> = this.Bind(Async.AwaitTask t, f)
member this.Bind(t: Task, f: unit -> Async<'b>) : Async<'b> = this.Bind(Async.AwaitTask t, f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment