3 people like it.

Await Computation Expression (Task + Async Interoperability)

When writing asynchronous code in F#, one often needs to call methods in the .NET BCL that return Task or Task rather than the F# native Async<'a> type. While the Async.AwaitTask function can convert a Task into an Async<'a>, there is some cognitive overhead in having to keep track of which functions return Task and which functions are Async. To simplify this interoperability, this code provides new `await` computation expression that supports using both Async<'a> and Task or Task inside it. This works by unifying the Task and Async types in the Awaitable DU, and overloading the Bind, ReturnFrom, Combine, and Using methods on the AwaitableBuilder Computation Builder to handle Awaitable<'a>, Async<'a>, Task, and Task.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
114: 
115: 
116: 
117: 
118: 
119: 
120: 
121: 
122: 
123: 
124: 
125: 
126: 
127: 
128: 
129: 
130: 
131: 
132: 
133: 
134: 
135: 
136: 
137: 
138: 
139: 
140: 
open System
open System.Threading
open System.Threading.Tasks

/// A standard representation of an awaitable action, such as an F# Async Workflow or a .NET Task
[<Struct>]
type Awaitable<'a> =
| AsyncWorkflow of async: Async<'a>
| DotNetTask of task: Task<'a>

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Awaitable =
    let private await f g = function
    | AsyncWorkflow a -> f a
    | DotNetTask t -> g t

    /// Convert an F# Async Workflow to an Awaitable
    let ofAsync = AsyncWorkflow

    /// Convert a .NET Event into an Awaitable
    let ofEvent event = Async.AwaitEvent event |> AsyncWorkflow

    /// Convert a .NET Task<T> into an Awaitable
    let ofTask = DotNetTask

    /// Convert a .NET Task into an Awaitable
    let ofUnitTask (t: Task) =
        t.ContinueWith(fun (task: Task) -> 
            let tcs = TaskCompletionSource<unit>()
            if task.Status = TaskStatus.Canceled
            then tcs.SetCanceled()
            elif task.Status = TaskStatus.Faulted
            then tcs.SetException(task.Exception)
            else tcs.SetResult()
            tcs.Task).Unwrap() |> DotNetTask

    /// Start an Awaitable, if it is not already running
    let start = await Async.Start <| fun t -> if t.Status = TaskStatus.Created then t.Start()

    /// Create an Awaitable that will sleep for the specified amount of time
    let sleep = Async.Sleep >> AsyncWorkflow
    
    /// Convert an Awaitable into an F# Async Workflow
    let toAsync<'a> : Awaitable<'a> -> Async<'a> = await id Async.AwaitTask

    /// Convert an Awaitable into a .NET Task<T>
    let toTask<'a> : Awaitable<'a> -> Task<'a>  = await Async.StartAsTask id

    /// Construct an Awaitable from an existing value
    let value<'a> : 'a -> Awaitable<'a> = async.Return >> AsyncWorkflow
    
    /// Synchronously wait for the Awaitable to complete and return the result
    let wait<'a> : Awaitable<'a> -> 'a = await Async.RunSynchronously <| fun t -> t.RunSynchronously(); t.Result
    
    /// Run a set of Awaitables in parallel and create a single Awaitable that returns all of the resutls in an array
    let Parallel<'a> : Awaitable<'a> seq -> Awaitable<'a []> = 
        Seq.map toAsync >> Async.Parallel >> AsyncWorkflow
        
    /// Monadic bind, extract the value from inside an Awaitable and pass it to the given function
    let bind f = function
    | AsyncWorkflow a -> 
        async.Bind(a, f >> toAsync) |> AsyncWorkflow        
    | DotNetTask t -> t.ContinueWith(fun (c: Task<_>) -> 
        (c.Result |> f |> toTask)).Unwrap() |> DotNetTask

    /// Delay the evaluation of the given function, wrapping it in an Awaitable
    let delay f = bind f (value ())

    /// Combine an Awaitable<unit> with an Awaitable<'a>, 
    /// running them sequentially and returning an Awaitable<'a>
    let combine a b = bind (fun () -> b) a

    /// Evaluate an Awaitable<'a> until the guard condition returns false
    let rec doWhile guard a = 
        if guard ()
        then bind (fun () -> doWhile guard a) a
        else Task.FromResult() |> DotNetTask

    /// Try to evaluate the given Awaitable function, then unconditionally run the `finally`
    let tryFinally fin (f: unit -> Awaitable<_>) =
        async.TryFinally(f() |> toAsync, fin) |> AsyncWorkflow

    /// Try to evaluate the given Awaitable function, running the `catch` if an exception is thrown
    let tryCatch catch (f: unit -> Awaitable<_>) =
        async.TryWith(f() |> toAsync, catch >> toAsync) |> AsyncWorkflow

    /// Scope the given IDisposable resource to the Awaitable function,
    /// disposing the resource when the Awaitable has completed
    let using (a: 'a :> IDisposable) (f: 'a -> Awaitable<_>) =
        let dispose =
            let mutable flag = 0
            fun () ->
                if Interlocked.CompareExchange(&flag, 1, 0) = 0 && a |> box |> isNull |> not
                then (a :> IDisposable).Dispose()
        tryFinally dispose (fun () -> bind f (value a))

    /// Evaluate the given Awaitable function for each element in the sequence
    let forEach (items: _ seq) f = 
        using (items.GetEnumerator()) (fun e -> doWhile (fun () -> e.MoveNext()) (delay <| fun () -> f e.Current))

    /// Ignore the result of an Awaitable<'a> and return an Awaitable<unit>
    let ignore<'a> : Awaitable<'a> -> Awaitable<unit> = bind (ignore >> value)

type AwaitableBuilder () =
    member inline __.Bind (x, f) = Awaitable.bind f x
    member inline __.Bind (a, f) = a |> AsyncWorkflow |> Awaitable.bind f
    member inline __.Bind (t, f) = t |> DotNetTask |> Awaitable.bind f    
    member inline __.Delay f = Awaitable.delay f
    member inline __.Return x = Awaitable.value x
    member inline __.ReturnFrom (x: Awaitable<_>) = x
    member inline __.ReturnFrom a = a |> AsyncWorkflow
    member inline __.ReturnFrom t = t |> DotNetTask
    member inline __.Zero () = async.Return() |> AsyncWorkflow
    member inline __.Combine (a, b) = Awaitable.combine a b
    member inline __.Combine (a, b) = Awaitable.combine (AsyncWorkflow a) b
    member inline __.Combine (a, b) = Awaitable.combine (DotNetTask a) b
    member inline __.While (g, a) = Awaitable.doWhile g a
    member inline __.For (s, f) = Awaitable.forEach s f
    member inline __.TryWith (f, c) = Awaitable.tryCatch c f
    member inline __.TryFinally (f, fin) = Awaitable.tryFinally fin f
    member inline __.Using (d, f) = Awaitable.using d f
    member inline __.Using (d, f) = Awaitable.using d (f >> AsyncWorkflow)
    member inline __.Using (d, f) = Awaitable.using d (f >> DotNetTask)

[<AutoOpen>]
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module AwaitableBuilder =
    let await = AwaitableBuilder()



// Example Usage:
let awaitable =
    await {
        let! asyncValue = async.Return(3)
        let! taskValue = Task.Run(fun () -> 5)
        return! async { return asyncValue * taskValue }
    }

printfn "Awaitable Result: %d" (awaitable |> Awaitable.wait)
namespace System
namespace System.Threading
namespace System.Threading.Tasks
Multiple items
type StructAttribute =
  inherit Attribute
  new : unit -> StructAttribute

Full name: Microsoft.FSharp.Core.StructAttribute

--------------------
new : unit -> StructAttribute
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
Multiple items
type Task =
  new : action:Action -> Task + 7 overloads
  member AsyncState : obj
  member ContinueWith : continuationAction:Action<Task> -> Task + 9 overloads
  member CreationOptions : TaskCreationOptions
  member Dispose : unit -> unit
  member Exception : AggregateException
  member Id : int
  member IsCanceled : bool
  member IsCompleted : bool
  member IsFaulted : bool
  ...

Full name: System.Threading.Tasks.Task

--------------------
type Task<'TResult> =
  inherit Task
  new : function:Func<'TResult> -> Task<'TResult> + 7 overloads
  member ContinueWith : continuationAction:Action<Task<'TResult>> -> Task + 9 overloads
  member Result : 'TResult with get, set
  static member Factory : TaskFactory<'TResult>

Full name: System.Threading.Tasks.Task<_>

--------------------
Task(action: Action) : unit
Task(action: Action, cancellationToken: CancellationToken) : unit
Task(action: Action, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj) : unit
Task(action: Action, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj, cancellationToken: CancellationToken) : unit
Task(action: Action<obj>, state: obj, creationOptions: TaskCreationOptions) : unit
Task(action: Action<obj>, state: obj, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit

--------------------
Task(function: Func<'TResult>) : unit
Task(function: Func<'TResult>, cancellationToken: CancellationToken) : unit
Task(function: Func<'TResult>, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj) : unit
Task(function: Func<'TResult>, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj, cancellationToken: CancellationToken) : unit
Task(function: Func<obj,'TResult>, state: obj, creationOptions: TaskCreationOptions) : unit
Task(function: Func<obj,'TResult>, state: obj, cancellationToken: CancellationToken, creationOptions: TaskCreationOptions) : unit
Multiple items
type CompilationRepresentationAttribute =
  inherit Attribute
  new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute
  member Flags : CompilationRepresentationFlags

Full name: Microsoft.FSharp.Core.CompilationRepresentationAttribute

--------------------
new : flags:CompilationRepresentationFlags -> CompilationRepresentationAttribute
type CompilationRepresentationFlags =
  | None = 0
  | Static = 1
  | Instance = 2
  | ModuleSuffix = 4
  | UseNullAsTrueValue = 8
  | Event = 16

Full name: Microsoft.FSharp.Core.CompilationRepresentationFlags
CompilationRepresentationFlags.ModuleSuffix: CompilationRepresentationFlags = 4
val private await : f:'a -> g:'b -> ('c -> 'd)

Full name: Script.AwaitableModule.await
val f : 'a
val g : 'b
val ofAsync : obj

Full name: Script.AwaitableModule.ofAsync


 Convert an F# Async Workflow to an Awaitable
val ofEvent : event:IEvent<'a,'b> -> 'c (requires delegate and 'a :> Delegate)

Full name: Script.AwaitableModule.ofEvent


 Convert a .NET Event into an Awaitable
val event : IEvent<'a,'b> (requires delegate and 'a :> Delegate)
static member Async.AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
val ofTask : obj

Full name: Script.AwaitableModule.ofTask


 Convert a .NET Task<T> into an Awaitable
val ofUnitTask : t:Task -> 'a

Full name: Script.AwaitableModule.ofUnitTask


 Convert a .NET Task into an Awaitable
val t : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>) : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, continuationOptions: TaskContinuationOptions) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, scheduler: TaskScheduler) : Task<'TResult>
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, cancellationToken: CancellationToken) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>, continuationOptions: TaskContinuationOptions) : Task
Task.ContinueWith(continuationAction: Action<Task>, scheduler: TaskScheduler) : Task
Task.ContinueWith(continuationAction: Action<Task>, cancellationToken: CancellationToken) : Task
Task.ContinueWith<'TResult>(continuationFunction: Func<Task,'TResult>, cancellationToken: CancellationToken, continuationOptions: TaskContinuationOptions, scheduler: TaskScheduler) : Task<'TResult>
Task.ContinueWith(continuationAction: Action<Task>, cancellationToken: CancellationToken, continuationOptions: TaskContinuationOptions, scheduler: TaskScheduler) : Task
val task : Task
val tcs : TaskCompletionSource<unit>
Multiple items
type TaskCompletionSource<'TResult> =
  new : unit -> TaskCompletionSource<'TResult> + 3 overloads
  member SetCanceled : unit -> unit
  member SetException : exception:Exception -> unit + 1 overload
  member SetResult : result:'TResult -> unit
  member Task : Task<'TResult>
  member TrySetCanceled : unit -> bool
  member TrySetException : exception:Exception -> bool + 1 overload
  member TrySetResult : result:'TResult -> bool

Full name: System.Threading.Tasks.TaskCompletionSource<_>

--------------------
TaskCompletionSource() : unit
TaskCompletionSource(creationOptions: TaskCreationOptions) : unit
TaskCompletionSource(state: obj) : unit
TaskCompletionSource(state: obj, creationOptions: TaskCreationOptions) : unit
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
property Task.Status: TaskStatus
type TaskStatus =
  | Created = 0
  | WaitingForActivation = 1
  | WaitingToRun = 2
  | Running = 3
  | WaitingForChildrenToComplete = 4
  | RanToCompletion = 5
  | Canceled = 6
  | Faulted = 7

Full name: System.Threading.Tasks.TaskStatus
field TaskStatus.Canceled = 6
TaskCompletionSource.SetCanceled() : unit
field TaskStatus.Faulted = 7
TaskCompletionSource.SetException(exceptions: Collections.Generic.IEnumerable<exn>) : unit
TaskCompletionSource.SetException(exception: exn) : unit
property Task.Exception: AggregateException
TaskCompletionSource.SetResult(result: unit) : unit
property TaskCompletionSource.Task: Task<unit>
val start : (obj -> obj)

Full name: Script.AwaitableModule.start


 Start an Awaitable, if it is not already running
static member Async.Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
val t : obj
field TaskStatus.Created = 0
val sleep : (int -> obj)

Full name: Script.AwaitableModule.sleep


 Create an Awaitable that will sleep for the specified amount of time
static member Async.Sleep : millisecondsDueTime:int -> Async<unit>
val toAsync<'a> : (obj -> Async<'a>)

Full name: Script.AwaitableModule.toAsync


 Convert an Awaitable into an F# Async Workflow
val id : x:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.id
static member Async.AwaitTask : task:Task -> Async<unit>
static member Async.AwaitTask : task:Task<'T> -> Async<'T>
val toTask<'a> : (obj -> Task<'a>)

Full name: Script.AwaitableModule.toTask


 Convert an Awaitable into a .NET Task<T>
static member Async.StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
val value<'a> : ('a -> obj)

Full name: Script.AwaitableModule.value


 Construct an Awaitable from an existing value
member AsyncBuilder.Return : value:'T -> Async<'T>
val wait<'a> : (obj -> 'a)

Full name: Script.AwaitableModule.wait


 Synchronously wait for the Awaitable to complete and return the result
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
Multiple items
val Parallel<'a> : (seq<obj> -> obj)

Full name: Script.AwaitableModule.Parallel


 Run a set of Awaitables in parallel and create a single Awaitable that returns all of the resutls in an array


--------------------
type Parallel =
  static member For : fromInclusive:int * toExclusive:int * body:Action<int> -> ParallelLoopResult + 11 overloads
  static member ForEach<'TSource> : source:IEnumerable<'TSource> * body:Action<'TSource> -> ParallelLoopResult + 19 overloads
  static member Invoke : [<ParamArray>] actions:Action[] -> unit + 1 overload

Full name: System.Threading.Tasks.Parallel
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
val bind : f:'a -> ('b -> 'c)

Full name: Script.AwaitableModule.bind


 Monadic bind, extract the value from inside an Awaitable and pass it to the given function
member AsyncBuilder.Bind : computation:Async<'T> * binder:('T -> Async<'U>) -> Async<'U>
val delay : f:'a -> 'b

Full name: Script.AwaitableModule.delay


 Delay the evaluation of the given function, wrapping it in an Awaitable
val combine : a:'a -> b:'b -> 'c

Full name: Script.AwaitableModule.combine


 Combine an Awaitable<unit> with an Awaitable<'a>,
 running them sequentially and returning an Awaitable<'a>
val a : 'a
val b : 'b
val doWhile : guard:(unit -> bool) -> a:'a -> 'b

Full name: Script.AwaitableModule.doWhile


 Evaluate an Awaitable<'a> until the guard condition returns false
val guard : (unit -> bool)
val tryFinally : fin:(unit -> unit) -> f:(unit -> obj) -> 'a

Full name: Script.AwaitableModule.tryFinally


 Try to evaluate the given Awaitable function, then unconditionally run the `finally`
val fin : (unit -> unit)
val f : (unit -> obj)
member AsyncBuilder.TryFinally : computation:Async<'T> * compensation:(unit -> unit) -> Async<'T>
val tryCatch : catch:(exn -> obj) -> f:(unit -> obj) -> 'a

Full name: Script.AwaitableModule.tryCatch


 Try to evaluate the given Awaitable function, running the `catch` if an exception is thrown
val catch : (exn -> obj)
member AsyncBuilder.TryWith : computation:Async<'T> * catchHandler:(exn -> Async<'T>) -> Async<'T>
val using : a:'a -> f:('a -> 'a0) -> 'b (requires 'a :> IDisposable)

Full name: Script.AwaitableModule.using


 Scope the given IDisposable resource to the Awaitable function,
 disposing the resource when the Awaitable has completed
val a : #IDisposable
type IDisposable =
  member Dispose : unit -> unit

Full name: System.IDisposable
val f : (#IDisposable -> 'a0)
val dispose : (unit -> unit)
val mutable flag : int
type Interlocked =
  static member Add : location1:int * value:int -> int + 1 overload
  static member CompareExchange : location1:int * value:int * comparand:int -> int + 6 overloads
  static member Decrement : location:int -> int + 1 overload
  static member Exchange : location1:int * value:int -> int + 6 overloads
  static member Increment : location:int -> int + 1 overload
  static member Read : location:int64 -> int64

Full name: System.Threading.Interlocked
Interlocked.CompareExchange<'T (requires reference type)>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T
Interlocked.CompareExchange(location1: byref<nativeint>, value: nativeint, comparand: nativeint) : nativeint
Interlocked.CompareExchange(location1: byref<obj>, value: obj, comparand: obj) : obj
Interlocked.CompareExchange(location1: byref<float>, value: float, comparand: float) : float
Interlocked.CompareExchange(location1: byref<float32>, value: float32, comparand: float32) : float32
Interlocked.CompareExchange(location1: byref<int64>, value: int64, comparand: int64) : int64
Interlocked.CompareExchange(location1: byref<int>, value: int, comparand: int) : int
val box : value:'T -> obj

Full name: Microsoft.FSharp.Core.Operators.box
val isNull : value:'T -> bool (requires 'T : null)

Full name: Microsoft.FSharp.Core.Operators.isNull
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val forEach : items:seq<'a> -> f:('a -> 'b) -> 'c

Full name: Script.AwaitableModule.forEach


 Evaluate the given Awaitable function for each element in the sequence
val items : seq<'a>
val f : ('a -> 'b)
Collections.Generic.IEnumerable.GetEnumerator() : Collections.Generic.IEnumerator<'a>
val e : Collections.Generic.IEnumerator<'a>
Collections.IEnumerator.MoveNext() : bool
property Collections.Generic.IEnumerator.Current: 'a
val ignore<'a> : (obj -> obj)

Full name: Script.AwaitableModule.ignore


 Ignore the result of an Awaitable<'a> and return an Awaitable<unit>
Multiple items
type AwaitableBuilder =
  new : unit -> AwaitableBuilder
  member Bind : x:'a21 * f:'a22 -> 'a23
  member Bind : a:'a18 * f:'a19 -> 'a20
  member Bind : t:'a15 * f:'a16 -> 'a17
  member Combine : a:'a3 * b:'a4 -> 'a5
  member Combine : a:'t * b:'a1 -> 'a2
  member Combine : a:'q * b:'r -> 's
  member Delay : f:'a13 -> 'a14
  member For : s:seq<'l> * f:('l -> 'm) -> 'n
  member Return : x:'a12 -> obj
  ...

Full name: Script.AwaitableBuilder

--------------------
new : unit -> AwaitableBuilder
member AwaitableBuilder.Bind : x:'a21 * f:'a22 -> 'a23

Full name: Script.AwaitableBuilder.Bind
val x : 'a21
val f : 'a22
module Awaitable

from Script
val __ : AwaitableBuilder
member AwaitableBuilder.Bind : a:'a18 * f:'a19 -> 'a20

Full name: Script.AwaitableBuilder.Bind
val a : 'a18
val f : 'a19
member AwaitableBuilder.Bind : t:'a15 * f:'a16 -> 'a17

Full name: Script.AwaitableBuilder.Bind
val t : 'a15
val f : 'a16
member AwaitableBuilder.Delay : f:'a13 -> 'a14

Full name: Script.AwaitableBuilder.Delay
val f : 'a13
member AwaitableBuilder.Return : x:'a12 -> obj

Full name: Script.AwaitableBuilder.Return
val x : 'a12
member AwaitableBuilder.ReturnFrom : x:'a11 -> 'a11

Full name: Script.AwaitableBuilder.ReturnFrom
val x : 'a11
member AwaitableBuilder.ReturnFrom : a:'a9 -> 'a10

Full name: Script.AwaitableBuilder.ReturnFrom
val a : 'a9
member AwaitableBuilder.ReturnFrom : t:'a7 -> 'a8

Full name: Script.AwaitableBuilder.ReturnFrom
val t : 'a7
member AwaitableBuilder.Zero : unit -> 'a6

Full name: Script.AwaitableBuilder.Zero
member AwaitableBuilder.Combine : a:'a3 * b:'a4 -> 'a5

Full name: Script.AwaitableBuilder.Combine
val a : 'a3
val b : 'a4
member AwaitableBuilder.Combine : a:'t * b:'a1 -> 'a2

Full name: Script.AwaitableBuilder.Combine
val a : 't
val b : 'a1
member AwaitableBuilder.Combine : a:'q * b:'r -> 's

Full name: Script.AwaitableBuilder.Combine
val a : 'q
val b : 'r
member AwaitableBuilder.While : g:(unit -> bool) * a:'o -> 'p

Full name: Script.AwaitableBuilder.While
val g : (unit -> bool)
val a : 'o
member AwaitableBuilder.For : s:seq<'l> * f:('l -> 'm) -> 'n

Full name: Script.AwaitableBuilder.For
val s : seq<'l>
val f : ('l -> 'm)
member AwaitableBuilder.TryWith : f:(unit -> obj) * c:(exn -> obj) -> 'k

Full name: Script.AwaitableBuilder.TryWith
val c : (exn -> obj)
member AwaitableBuilder.TryFinally : f:(unit -> obj) * fin:(unit -> unit) -> 'j

Full name: Script.AwaitableBuilder.TryFinally
member AwaitableBuilder.Using : d:'g * f:('g -> 'h) -> 'i (requires 'g :> IDisposable)

Full name: Script.AwaitableBuilder.Using
val d : #IDisposable
val f : (#IDisposable -> 'h)
member AwaitableBuilder.Using : d:'d * f:('d -> 'e) -> 'f (requires 'd :> IDisposable)

Full name: Script.AwaitableBuilder.Using
val f : (#IDisposable -> 'e)
member AwaitableBuilder.Using : d:'a * f:('a -> 'b) -> 'c (requires 'a :> IDisposable)

Full name: Script.AwaitableBuilder.Using
val f : (#IDisposable -> 'b)
Multiple items
type AutoOpenAttribute =
  inherit Attribute
  new : unit -> AutoOpenAttribute
  new : path:string -> AutoOpenAttribute
  member Path : string

Full name: Microsoft.FSharp.Core.AutoOpenAttribute

--------------------
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
val await : AwaitableBuilder

Full name: Script.AwaitableBuilderModule.await
val awaitable : obj

Full name: Script.awaitable
val asyncValue : 'a (requires member ( * ))
val taskValue : 'a (requires member ( * ))
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn

More information

Link:http://fssnip.net/7Va
Posted:22 days ago
Author:Aaron Eshbach
Tags: async , await , computation expression , task