Mi chiedo, perché la strategia predefinita di gestione di MailboxProcessor
di gestire le eccezioni è semplicemente ignorare in modo invisibile. Ad esempio:MailboxProcessor ed eccezioni
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
e non succede nulla. Non vi è alcun arresto irreversibile nell'esecuzione del programma, oppure viene visualizzata una finestra di messaggio con "Un'eccezione non gestita". Niente.
Questa situazione peggiora se qualcuno utilizza il metodo PostAndReply
: un deadlock garantito come risultato.
Eventuali motivi per tale comportamento?
Sì, può essere implementato, ovviamente. Non capisco, perché * il comportamento predefinito * è così senza parole. Può rilanciare l'eccezione nel caso in cui non ci siano gestori in 'MailboxProcessor.add_Error', ad esempio. È difficile eseguire il debug del codice Async/multithread. Perché dovremmo rendere questo compito ancora più difficile? – qehgt
È possibile sostenere che sarebbe preferibile annullare il processo (eccezione non gestita) se non sono stati associati gestori. Non ricordo la logica. – Brian
Un problema con rilanciando le eccezioni è che si perde la traccia dello stack - ad esempio 'async {failwith" bad "}' dà una traccia stack che punta in profondità nelle librerie F #, che può essere fastidioso debugging - apparentemente questa è una limitazione .NET su eccezioni di rilancio su un thread diverso –