Me pregunto por qué la estrategia predeterminada de MailboxProcessor
para manejar excepciones es solo ignorarlas silenciosamente. Por ejemplo:MailboxProcessor y excepciones
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop() =
async { printfn "waiting for data..."
let! data = inbox.Receive()
failwith "fail" // simulate throwing of an exception
printfn "Got: %d" data
return! loop()
}
loop())
()
counter.Post(42)
counter.Post(43)
counter.Post(44)
Async.Sleep 1000 |> Async.RunSynchronously
y no ocurre nada. No hay una parada fatal de la ejecución del programa, o aparece un cuadro de mensaje con "Una excepción no controlada". Nada.
Esta situación empeora si alguien usa el método PostAndReply
: como resultado, se produce un punto muerto garantizado.
¿Algún motivo para tal comportamiento?
Sí, se puede implementar, por supuesto. No entiendo por qué el comportamiento * predeterminado * es tan sin palabras. Puede volver a lanzar la excepción en caso de que no haya controladores en 'MailboxProcessor.add_Error', por ejemplo. Es difícil depurar el código Async/multiproceso. ¿Por qué deberíamos hacer esta tarea aún más difícil? – qehgt
Puede argumentar que sería mejor anular el proceso (excepción no controlada) si no se han adjuntado controladores. No recuerdo el razonamiento. – Brian
Un problema con las excepciones de reintroducción es que pierde el seguimiento de la pila; por ejemplo, 'async {failwith" bad "}' da un rastro de pila que apunta profundo en las bibliotecas F #, lo que puede ser una depuración molesta; aparentemente, esto es una limitación .NET en reintroducción de excepciones en un hilo diferente –