I’m implementing the .NET Generic Host IHostedService
interface in an F# console app. in the StartAsync
method, I want to make an async call via HttpClient
, so I have wrapped the body of the method in an async computation expression. However, I’m not sure how to return the computation expression as a Task
to match StartAsync
's expected return type.
As you can see, I have piped the async computation expression into Async.StartAsTask
, and then explicitly cast that as a Task
. This feels clunky to me. Is there a better way?
module CustomHostedService
open Microsoft.Extensions.Hosting
open System.Threading.Tasks
open System.Net.Http
open System
type CustomHostedService(httpClientFactory: IHttpClientFactory, appLifetime: IApplicationLifetime) =
let _httpClient = httpClientFactory.CreateClient()
let _appLifetime = appLifetime
interface IHostedService with
member this.StartAsync(cancellationToken: System.Threading.CancellationToken): System.Threading.Tasks.Task =
async {
printfn "Starting service..."
use requestMsg = new HttpRequestMessage(HttpMethod.Get, "https://www.microsoft.com")
// Set per-request state
requestMsg.Properties.["CustomerId"] <- Guid.Parse("cc37bdc9-37c7-47d2-b8ad-dcbf6f691471");
// Execute the request.
use! response = _httpClient.SendAsync(requestMsg) |> Async.AwaitTask
// Do something with the response
// We're done. Tell the application to shut down.
_appLifetime.StopApplication()
} |> Async.StartAsTask :> Task
member this.StopAsync(cancellationToken: System.Threading.CancellationToken): System.Threading.Tasks.Task =
printfn "Stopping service..."
Task.CompletedTask