Reputation: 8997
I want to offload the handler used for a subscription for RabbitMQ with EasyNetQ, in C# I get what I want cause the handler itself is tagged as async
and hence inside I can then await the offloading, in other words:
var subscription = bus.PubSub.Subscribe<Message>("subscriptionId", async message =>
{
// Await Offloading
await Task.Run(() =>
{
// If it throws something here, it still bubble up to the handler
});
});
However, in F# I am completely puzzled, does the C# code can be properly translated to F#?
I started to draft something, but this is clearly not the solution
let handle (message: Message) = async{
printfn "%A" message
}
let subscription = bus.PubSub.Subscribe<Message>("subscriptionId", fun message ->
handle message
|> Async.Start
)
This F# snippet does not properly address my question, it's two-folded:
handle
is not awaitedhandle
do not bubble up to the fun
handlerAnother improper way to tackle the problem is:
let handle (message: Message) = async{
printfn "%A" message
}
let subscription = bus.PubSub.Subscribe<Message>("subscriptionId", fun message ->
handle message
|> Async.RunSynchronously
)
But although this is awaited (unlike the snippet above), this one runs on the same thread and does not offload the work onto a threadpool thread.
Upvotes: 3
Views: 261
Reputation: 13577
A close approximation of what you're looking for would be something like this:
bus.PubSub.SubscribeAsync<Message>("subscriptionId", fun message ->
async {
do! handle message
}
|> Async.StartAsTask :> Task)
async-await
constructs in C# only provide syntax sugar for composing Tasks
- all the .***Async
methods that are now ubiquitous in .NET apis are entirely usable from F#, though sometimes the necessary plumbing code can get unwieldy. The situation there might be improving in the future though.
Upvotes: 2