Это невозможно именно в этом сценарии, но вы можете определить тип своего сообщения, включив в него AsyncReplyChannel‹'t>, что позволяет использовать MailboxProcessor.PostAndReply вместо Post. Таким образом, вызывающий код может (синхронно или асинхронно) ожидать ответного значения или, по крайней мере, индикации того, что обработка завершена.
Ваш измененный исходный код может выглядеть так:
[<TestMethod>]
member this.TestMailboxProcessor() =
let mailboxProcessor =
MailboxProcessor<string * AsyncReplyChannel<unit>>.Start(fun inbox ->
async {
while true do
let! msg, replyChannel = inbox.Receive()
printfn "agent got message %s" msg
(*
Reply takes a value of the generic param of
AsyncReplyChannel<'t>, in this case just a unit
*)
replyChannel.Reply()
}
)
(*
You can't create an AsyncReplyChannel<'t> value, but this does it for you.
Also always, always use timeouts when awaiting message replies.
*)
mailboxProcessor.PostAndReply(
(fun replyChannel -> "ping", replyChannel),
timeout = 1000)
(* This gets printed only after the message has been posted and processed *)
Console.WriteLine "message posted"
Assert.IsTrue(true)
Тем не менее, MailboxProcessors — это немного сложная тема, поэтому убедитесь, что вы всегда используете тайм-ауты, иначе в случае ошибок в вашем коде или исключений, прерывающих цикл обработки сообщений, ваш код зависнет навсегда. Плохо в тестах, еще хуже в продакшене.
person
Honza Brestan
schedule
03.04.2018