F #: Как «ожидать» функцию в обработчике, чтобы исключение все еще доходило до обработчика? - PullRequest
3 голосов
/ 31 мая 2019

Я хочу разгрузить обработчик, используемый для подписки на RabbitMQ с EasyNetQ, в C # я получаю то, что хочу, потому что сам обработчик помечен как async, и, следовательно, внутри я могу ожидать разгрузки, другими словами:

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
    });
});

Однако в F # я полностью озадачен, может ли код C # быть правильно переведен в F #?

Я начал что-то составлять, но это явно не решение

let handle (message: Message) = async{
    printfn "%A" message
}

let subscription = bus.PubSub.Subscribe<Message>("subscriptionId", fun message ->
    handle message
    |> Async.Start
    ) 

Этот фрагмент кода F # неправильно отвечает на мой вопрос, он состоит из двух частей:

  • handle не ожидается
  • исключения, которые могут возникнуть в handle, не всплывают до обработчика fun

Другой неправильный способ решения проблемы:

let handle (message: Message) = async{
    printfn "%A" message
}

let subscription = bus.PubSub.Subscribe<Message>("subscriptionId", fun message ->
    handle message
    |> Async.RunSynchronously
    ) 

Но хотя это и ожидается (в отличие от приведенного выше фрагмента), он выполняется в том же потоке и не выгружает работу в поток пула потоков.

1 Ответ

2 голосов
/ 01 июня 2019

Точное приближение того, что вы ищете, будет примерно таким:

bus.PubSub.SubscribeAsync<Message>("subscriptionId", fun message ->
        async {
            do! handle message
        }
        |> Async.StartAsTask :> Task) 
Конструкции

async-await в C # предоставляют только синтаксический сахар для составления Tasks - все методы .***Async, которые теперь повсеместно используются в .NET apis, полностью доступны из F #, хотя иногда необходимый сантехнический код может быть громоздким. Ситуация там может улучшиться в будущем.

...