Ich bin neu zu F # und versuchen, einige C# ASP.NET Core-Code in F # übersetzenF # Syntax für Asynchron-Controller-Methoden in ASP.NET-Core
Es gibt einen Controller C# ist here, und eine Arbeits übersetzt F # Controller here
Obwohl ich es funktioniert habe, kann ich nicht herausfinden, wie die Controller-Aktionen async zu machen. Die Methoden rufen einen asynchronen Code für ein Commands-Objekt und ein Queries-Objekt auf, die injiziert werden. Die Befehle und Abfragen sind derzeit in C# implementiert.
So zum Beispiel ein paar der Asynchron-C# Controller-Methoden sind:
public async Task<IEnumerable<ToDoItem>> Get()
{
return await queries.GetAll();
}
[HttpGet("{id}", Name = "GetTodo")]
public async Task<IActionResult> GetById(string id)
{
var item = await queries.Find(id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
public async Task<IActionResult> Create([FromBody] ToDoItem item)
{
if (item == null)
{
return BadRequest();
}
if (string.IsNullOrEmpty(item.Id)) item.Id = Guid.NewGuid().ToString();
await commands.Add(item);
return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}
und ich habe diejenigen zu F # wie folgt übersetzt:
[<HttpGet>]
member __.Get() =
__.Queries.GetAll() // this should be awaited
[<HttpGet("{id}", Name = "GetFSTodo")>]
member __.GetToDoItem(id) =
let data = __.Queries.Find(id) // this should be awaited
if isNull data
then __.NotFound() :> IActionResult
else
new ObjectResult(data) :> IActionResult
[<HttpPost>]
member __.Create([<FromBody>] item:ToDoItem) =
item.Id <- Guid.NewGuid().ToString()
(__.Commands.Add(item)) |> ignore // this should be awaited
let rv = new RouteValueDictionary()
rv.Add("id",item.Id)
__.CreatedAtRoute("GetTodo", rv, item) :> IActionResult
Diese Methoden funktionieren, aber ich denke, sie sind nicht korrekt ausgeführt, da sie die asynchronen Aufrufe von Abfragen und Befehlen nicht erwarten. Ich habe einige Stunden mit Versuch und Irrtum geprügelt, aber jeder Versuch, die Controller-Methoden asynchron zu machen, führt dazu, dass sie keine Daten an den Browser zurücksenden, obwohl sie einen 200-Statuscode zurückgeben. Sie können sehen, einige meiner Versuche auskommentiert in der F# controller
Ich hoffe, einige F # Guru (s) könnte mir helfen, diese Methoden korrekt zu übersetzen. Es gibt einige ziemlich schlechte Tooling-Probleme in Bezug auf F # mit ASP.NET Core, was es für einen Neuling wie mich schwieriger macht. Ich habe diese Probleme in den Code erwähnt, aber ich denke, wenn ich lernen kann, für diese Methoden zu lösen, dann wird die gleiche Lösung wahrscheinlich für die anderen Methoden gelten.
Der Code befindet sich in einem öffentlichen Repository, so dass Sie es problemlos in VS 2015 ausprobieren können, solange Sie über die neuesten VS-Updates und den neuesten ASP verfügen.NET Core-Werkzeuge installiert
UPDATE:
dank der verlinkten Beitrag von Mark Seemann, ich war in der Lage, diese Methode zu bekommen arbeiten async
[<HttpGet("{id}", Name = "GetFSTodo")>]
member __.GetToDoItem(id) =
async {
let! data = __.Queries.Find(id) |> asyncReturn
if isNull data
then return __.NotFound() :> IActionResult
else
return new ObjectResult(data) :> IActionResult }
|> Async.StartAsTask
unter Verwendung der Hilfsfunktion
let asyncReturn x = async { return x }
Ich kämpfe immer noch mit dieser Methode
[<HttpGet>]
member __.Get() =
async {
let! data = __.Queries.GetAll() |> asyncReturn
return data }
|> Async.StartAsTask
, die aus dieser C# Methode übersetzt:
[HttpGet]
public async Task<IEnumerable<ToDoItem>> Get()
{
return await queries.GetAll();
}
das # Methode funktioniert Asynchron-F, aber es unterschiedlichen json Ausgang als die C# -Version
C#
[{"id":"4f4e1596-6a48-4854-9982-7a2568aa1b1b","title":"add input validation","isDone":false,"dateAdded":"2016-09-20T21:16:04.8791044Z"},{"id":"9929b657-6a53-40b6-8c1c-1e4d0db593cd","title":"make F# controller async","isDone":false,"dateAdded":"2016-09-21T19:36:44.6650776Z"},{"id":"5bb5f544-6289-4051-ad65-d0dc016128e7","title":"learn F# basics","isDone":true,"dateAdded":"2016-09-22T11:59:00"},{"id":"e5e06118-c49f-496a-8175-9719ea72beed","title":"monkey business","isDone":false,"dateAdded":"2016-09-22T16:22:20.3133161Z"},{"id":"af0db8f2-6b49-4e31-86fa-e27c8e091f42","title":"funky bidness","isDone":false,"dateAdded":"2016-09-22T16:23:35.1175195Z"}]
F#
{"result":[{"id":"4f4e1596-6a48-4854-9982-7a2568aa1b1b","title":"add input validation","isDone":false,"dateAdded":"2016-09-20T21:16:04.8791044Z"},{"id":"9929b657-6a53-40b6-8c1c-1e4d0db593cd","title":"make F# controller async","isDone":false,"dateAdded":"2016-09-21T19:36:44.6650776Z"},{"id":"5bb5f544-6289-4051-ad65-d0dc016128e7","title":"learn F# basics","isDone":true,"dateAdded":"2016-09-22T11:59:00"},{"id":"e5e06118-c49f-496a-8175-9719ea72beed","title":"monkey business","isDone":false,"dateAdded":"2016-09-22T16:22:20.3133161Z"},{"id":"af0db8f2-6b49-4e31-86fa-e27c8e091f42","title":"funky bidness","isDone":false,"dateAdded":"2016-09-22T16:23:35.1175195Z"}],"id":65,"exception":null,"status":5,"isCanceled":false,"isCompleted":true,"creationOptions":0,"asyncState":null,"isFaulted":false}
so noch produziert ich, wie man etwas Hilfe gebrauchen könnte machen die F # Version die erwartete Ausgabe
versuchen Async.AwaitTask – Ringil
Sie können ein Beispiel für eine asynchrone Controller-Aktion gegen Ende dieses Blog-Post sehen: http : //blog.ploeh.dk/2016/04/11/async-as-surrogate-io Hilft das? –
@ mark-seemann danke! Ich habe ein paar Fortschritte dank Ihrer Post, und habe meine Frage aktualisiert in der Hoffnung auf weitere Erkenntnisse –