-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Support F# async in actions #5570
Comments
If the approach is correct and approved as idea, can be put as |
/cc @Eilon thoughts? Having looked at the xunit approach, I like that they avoid adding a hard dependency on any F# libraries. |
I think we should do this. PS: Whatever we do here we'll want similar logic in Common because SignalR will be the next thing to implement this. |
If it's ok to hardcode it (clean job and reusable obv) for now as suggested, it will be possible to refactor out and move as external library (initialized in For example for aspnet core handlers, we dont need changes, we just use an extension method to overload let myHandler (context: HttpContext) = async {
do! context.Response.WriteAsync("Hello World from F#!") |> Async.AwaitTask
}
app.Run(myHandler) And extension will be inside an helper lib soon (need to publish that 😄 , but following code is ok too to embedd) [<AutoOpen>]
module Async =
// Async<unit> -> Task
let inline StartAsPlainTask (work : Async<unit>) = work |> Async.StartAsTask :> Task
//Extension method used to Run an Async<unit> as RequestDelegate
type Microsoft.AspNetCore.Builder.IApplicationBuilder with
member this.Run(handler : HttpContext -> Async<unit>) =
this.Run(RequestDelegate(handler >> StartAsPlainTask)) I hope to resolve it once and for all for all libs, but no clue how to do it, so fix every lib when needed is the best current option. |
@rynowak @Eilon @davidfowl sry for ping, just to not stop the discussion, because i'd like to add that if is approved as idea. |
Would that mean that type MyController () =
inherit Controller ()
// Would this be possible?
member this.IndexProperty = async {
return this.View ()
}
// Or does it have to be a method?
member this.IndexMethod () = async {
return this.View ()
} |
@nikonthethird - no plans to change what we consider an action as part of this work, only methods. You could write something that adds support properties if you want to, but out of the box we'd only consider methods. |
Hi @enricosada , sorry for the delay. We would certainly accept a PR for this if you have time to work for it. |
See #6040 - while were here we should do valuetask as well |
Done since dotnet/extensions#221 now understands Have added a functional test to show it works end-to-end: #6240 |
Support F#
async
like theTask
based async in actions.So an action like the following can be used OOTB.
I added an example aspnet project with both F# async and current workaround actions.
Example is based on
dotnet new -l fsharp -t web
template inpreview4
, but is the same for all sdk versions (preview2 etc)The f# async
Home/About
doesnt work (async
class is converted as string =>{}
), converting asTask
works inHome/About2
The workaround is to call
Async.StartAsTask
before returning theFSharpAsync
, so is converted asTask
.How to implement that.
Like xunit does, recognize the result is
FSharpAsync
and invokeAsync.StartAsTask
(ref xunit commit to add f# async support xunit/xunit@a2aa665 )In previous aspnet was possibile to use an
ActionResult
.Speaking with @davidfowl he directed me into ObjectMethodExecutor class.
It should not give runtime performance penality (f# or c#), because it's done at initialization step also for normal
Task
, so at runtime just use a different delegate configured inObjectMethodExecutor
(inGetCoerceMethodCallExpression
?)/cc @panesofglass
The text was updated successfully, but these errors were encountered: