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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With