8 people like it.
Like the snippet!
Asynchronous Controller Helper
The snippet declares a helper for creating asynchronous controllers for ASP.NET MVC 3. It declares a new base class for asynchronous actions that exposes a computation builder for writing actions using F# asynchronous workflows.
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:
|
/// A computation builder that is almost the same as stnadard F# 'async'.
/// The differnece is that it takes an ASP.NET MVC 'AsyncManager' as an
/// argumnet and implements 'Run' opration, so that the workflow is
/// automatically executed after it is created (using the AsyncManager)
type AsyncActionBuilder(asyncMgr:Async.AsyncManager) =
(Boilerplate code that exposes 'async' operations)
/// Run the workflow automatically using ASP.NET AsyncManager
member x.Run(workflow) =
// Specify that there is some pending computation running
asyncMgr.OutstandingOperations.Increment() |> ignore
async { // Run the asynchronous workflow
let! res = workflow
// Store the result of the workflow, so that it
// is passed as an argument to 'Completed' method.
asyncMgr.Parameters.["result"] <- res
// Notify the manager that the workflow has completed
asyncMgr.OutstandingOperations.Decrement() |> ignore }
|> Async.Start
/// An F# specific asynchronous controller that provides
/// member 'AsyncAction' as a simple way of creating
/// asynchronous actions (hiding 'AsyncManager').
type FSharpAsyncController() =
inherit AsyncController()
member x.AsyncAction =
// Create new asynchronous builder using the current AsyncManager
new AsyncActionBuilder(x.AsyncManager)
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
|
[<HandleError>]
type MainController() =
inherit FSharpAsyncController()
// Standard synchronous action that just renders view
member x.Index() = x.View()
// Asynchronous action that uses F# asynchronous workflows
// to download a web page and then returns the length (in bytes)
member x.LengthAsync(url:string) = x.AsyncAction {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
return html.Length }
// Called after the completion of workflow created by 'LengthAsync'
// (the result of the workflow is passed as parameter named 'result')
member x.HelloCompleted(result:int) =
// Pass the result to the View
x.ViewData.Model <- result
x.View()
|
Multiple items
type AsyncActionBuilder =
new : asyncMgr:obj -> AsyncActionBuilder
member Bind : v:Async<'k> * f:('k -> Async<'l>) -> Async<'l>
member Combine : a:Async<unit> * b:Async<'j> -> Async<'j>
member Delay : f:(unit -> Async<'i>) -> Async<'i>
member For : s:seq<'g> * f:('g -> Async<unit>) -> Async<unit>
member Return : v:'h -> Async<'h>
member ReturnFrom : a:Async<'f> -> Async<'f>
member Run : workflow:Async<'a> -> unit
member TryFinally : a:Async<'e> * b:(unit -> unit) -> Async<'e>
member TryWith : a:Async<'d> * b:(exn -> Async<'d>) -> Async<'d>
...
Full name: Script.AsyncActionBuilder
A computation builder that is almost the same as stnadard F# 'async'.
The differnece is that it takes an ASP.NET MVC 'AsyncManager' as an
argumnet and implements 'Run' opration, so that the workflow is
automatically executed after it is created (using the AsyncManager)
--------------------
new : asyncMgr:obj -> AsyncActionBuilder
val asyncMgr : obj
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<'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<_>
member x.Bind(v, f) = async.Bind(v, f)
member x.Combine(a, b) = async.Combine(a, b)
member x.Delay(f) = async.Delay(f)
member x.Return(v) = async.Return(v)
member x.For(s, f) = async.For(s, f)
member x.ReturnFrom(a) = async.ReturnFrom(a)
member x.TryFinally(a, b) = async.TryFinally(a, b)
member x.TryWith(a, b) = async.TryWith(a, b)
member x.Using(r, f) = async.Using(r, f)
member x.While(c, f) = async.While(c, f)
member x.Zero() = async.Zero()
val x : AsyncActionBuilder
member AsyncActionBuilder.Run : workflow:Async<'a> -> unit
Full name: Script.AsyncActionBuilder.Run
Run the workflow automatically using ASP.NET AsyncManager
val workflow : Async<'a>
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
val async : AsyncBuilder
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val res : 'a
static member Async.Start : computation:Async<unit> * ?cancellationToken:Threading.CancellationToken -> unit
Multiple items
type FSharpAsyncController =
inherit obj
new : unit -> FSharpAsyncController
member AsyncAction : (obj -> 'b)
Full name: Script.FSharpAsyncController
An F# specific asynchronous controller that provides
member 'AsyncAction' as a simple way of creating
asynchronous actions (hiding 'AsyncManager').
--------------------
new : unit -> FSharpAsyncController
member FSharpAsyncController.AsyncAction : (obj -> 'b)
Full name: Script.FSharpAsyncController.AsyncAction
Multiple items
type MainController =
inherit FSharpAsyncController
new : unit -> MainController
member HelloCompleted : result:int -> 'a
member Index : unit -> 'c
member LengthAsync : url:string -> 'b
Full name: Script.MainController
--------------------
new : unit -> MainController
val x : MainController
member MainController.Index : unit -> 'c
Full name: Script.MainController.Index
member MainController.LengthAsync : url:string -> 'b
Full name: Script.MainController.LengthAsync
val url : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
property FSharpAsyncController.AsyncAction: obj -> 'b
Multiple items
type WebClient =
inherit Component
new : unit -> WebClient
member BaseAddress : string with get, set
member CachePolicy : RequestCachePolicy with get, set
member CancelAsync : unit -> unit
member Credentials : ICredentials with get, set
member DownloadData : address:string -> byte[] + 1 overload
member DownloadDataAsync : address:Uri -> unit + 1 overload
member DownloadFile : address:string * fileName:string -> unit + 1 overload
member DownloadFileAsync : address:Uri * fileName:string -> unit + 1 overload
member DownloadString : address:string -> string + 1 overload
...
Full name: System.Net.WebClient
--------------------
WebClient() : unit
member MainController.HelloCompleted : result:int -> 'a
Full name: Script.MainController.HelloCompleted
val result : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
More information