Cómo Async.AwaitTask en Tarea simple (no Tarea )?

Estoy tratando de consumir una biblioteca de C # en F #. La biblioteca hace un uso intensivo de async / await. Quiero usar dentro de un flujo de trabajo async { ... } en F #.

Veo que podemos Async.AwaitTask en los métodos async C # que devuelven Task , pero ¿qué pasa con los que devuelven plain Task ?

Quizás, ¿hay un ayudante para convertir estos a Async o para convertir Task to Task para que funcione con Async.AwaitTask ?

Puedes usar ContinueWith:

 let awaitTask (t: Task) = t.ContinueWith (fun t -> ()) |> Async.AwaitTask 

O AwaitIAsyncResult con infinito tiempo de espera:

 let awaitTask (t: Task) = t |> Async.AwaitIAsyncResult |> Async.Ignore 

Actualizar:

La biblioteca FSharp.Core para F # 4.0 ahora incluye una sobrecarga Async.AwaitTask que acepta una Task simple. Si está usando F # 4.0, entonces debe usar esta función central en lugar del siguiente código.


Respuesta original:

Si su tarea podría arrojar una excepción, probablemente también desee verificar esto. p.ej

 let awaitTask (task : Task) = async { do! task |> Async.AwaitIAsyncResult |> Async.Ignore if task.IsFaulted then raise task.Exception return () } 

Me gustó mucho la sugerencia de Ashley usando la composición de funciones. Además, puede extender el módulo Async de esta manera:

 module Async = let AwaitTaskVoid : (Task -> Async) = Async.AwaitIAsyncResult >> Async.Ignore 

Luego aparece en Intellisense junto con Async.AwaitTask. Se puede usar así:

 do! Task.Delay delay |> Async.AwaitTaskVoid 

Alguna sugerencia para un mejor nombre?

Para propagar correctamente tanto las excepciones como la cancelación, creo que necesita algo como esto (basado parcialmente en la respuesta eliminada de Tomáš Petříček):

 module Async = let AwaitVoidTask (task : Task) : Async = Async.FromContinuations(fun (cont, econt, ccont) -> task.ContinueWith(fun task -> if task.IsFaulted then econt task.Exception elif task.IsCanceled then ccont (OperationCanceledException()) else cont ()) |> ignore)