Chunked di Analisi con FParsec
Domanda
E ' possibile presentare ingresso a un FParsec parser in pezzi, come da una presa?Se non, è possibile recuperare il risultato attuale e non analizzata parte di un flusso di input in modo che io possa ottenere questo risultato?Sto cercando di eseguire i pezzi di input provenienti da SocketAsyncEventArgs
senza buffering i messaggi per intero.
Aggiornamento
Il motivo per notare l'uso di SocketAsyncEventArgs
era per indicare che l'invio di dati a un CharStream
potrebbe causare accesso asincrono sottostante Stream
.In particolare, sto cercando utilizzando un buffer circolare per spingere i dati in arrivo dalla presa di corrente.Mi ricordo il FParsec documentazione notare che il sottostante Stream
non deve essere letta in modo asincrono, quindi avevo programmato di controllo manuale della chunked di analisi.
Ultimate le domande:
- Posso utilizzare un buffer circolare sotto il mio
Stream
passato alCharStream
? - Non ho bisogno di preoccuparsi di me con il controllo manuale della chunking in questo scenario?
Soluzione
La versione normale di FParsec (anche se non l' Bassa Fiducia versione) legge l'input chunk-saggio, o "blocco-wise", come la chiamo io, in CharStream
documentazione.Quindi, se si crea un CharStream
da un System.IO.Stream
e il contenuto è abbastanza grande da occupare più CharStream
blocchi, è possibile avviare l'analisi prima di aver completamente recuperato l'ingresso.
Si noti, tuttavia, che il CharStream
consumerà il flusso di input in blocchi di un fisso (ma configurabile), ossiachiama l' Read
metodo di System.IO.Stream
come spesso come necessario per riempire un blocco completo.Quindi, se si analizza l'input più velocemente di quanto si può recuperare di nuovo ingresso, il CharStream
può bloccare anche se c'è già non analizzata ingresso, perché non c'è ancora abbastanza materiale per riempire un blocco completo.
Aggiornamento
La risposta(s) per le vostre domande ultime: 42.
Come implementare il
Stream
da cui si costruisce laCharStream
è interamente a voi.La restrizione si sta ricordando che esclude un accesso parallelo vale solo per ilCharStream
di classe, che non è thread-safe.Attuazione del
Stream
come un buffer circolare sarà probabilmente limitare la distanza massima oltre la quale si può tornare indietro.La dimensione del blocco di
CharStream
influenze quanto lontano si può tornare indietro quando ilStream
non supporta la ricerca.Il modo più semplice per analizzare l'input in modo asincrono è fare l'analisi in un async task (es.in un thread in background).Nel compito, si può semplicemente leggere il socket in modo sincrono, o, se non vi fidate buffering dal sistema operativo, è possibile utilizzare un flusso di classe, come la
BlockingStream
descritto nell'articolo che hai linkato nel secondo commento qui sotto.Se l'input può essere facilmente separati indipendenti blocchi (ad es.linee per una linea a base di formato di testo), potrebbe essere più efficiente suddividere in voi stessi e quindi analizzare l'ingresso di blocco per blocco.