Link to 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.

/// 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)typeAsyncActionBuilder(asyncMgr:Async.AsyncManager) =(Boilerplate code that exposes 'async' operations)/// Run the workflow automatically using ASP.NET AsyncManagermemberx.Run(workflow) =// Specify that there is some pending computation runningasyncMgr.OutstandingOperations.Increment() |>ignoreasync { // 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 completedasyncMgr.OutstandingOperations.Decrement() |>ignore }
|>Async.Start/// An F# specific asynchronous controller that provides /// member 'AsyncAction' as a simple way of creating /// asynchronous actions (hiding 'AsyncManager').typeFSharpAsyncController() =inheritAsyncController()
memberx.AsyncAction=// Create new asynchronous builder using the current AsyncManagernewAsyncActionBuilder(x.AsyncManager)

[<HandleError>]
typeMainController() =inheritFSharpAsyncController()
// Standard synchronous action that just renders viewmemberx.Index() =x.View()
// Asynchronous action that uses F# asynchronous workflows// to download a web page and then returns the length (in bytes)memberx.LengthAsync(url:string) =x.AsyncAction {
letwc=newWebClient()
let!html=wc.AsyncDownloadString(url)
returnhtml.Length }
// Called after the completion of workflow created by 'LengthAsync'// (the result of the workflow is passed as parameter named 'result')memberx.HelloCompleted(result:int) =// Pass the result to the Viewx.ViewData.Model<-resultx.View()

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)