Analyse de morceaux avec FPARSEC
Question
Est-il possible de soumettre une entrée à un analyseur FPARSEC en morceaux, comme dans une prise? Sinon, est-il possible de récupérer le résultat actuel et la partie non comparée d'un flux d'entrée afin que je puisse y parvenir? J'essaye d'exécuter les morceaux de contribution provenant de SocketAsyncEventArgs
sans tamponner des messages entiers.
Mise à jour
La raison de noter l'utilisation de SocketAsyncEventArgs
devait indiquer que l'envoi de données à un CharStream
pourrait entraîner un accès asynchrone à l'entrée sous-jacente Stream
. Plus précisément, je cherche à utiliser un tampon circulaire pour pousser les données provenant de la prise. Je me souviens de la documentation FPARSEC notant que le sous-jacent Stream
ne devrait pas être accessible de manière asynchrone, donc j'avais prévu de contrôler manuellement l'analyse de morceaux.
Questions ultimes:
- Puis-je utiliser un tampon circulaire sous mon
Stream
passé auCharStream
? - Ne dois-je pas m'inquiéter de contrôler manuellement le bunking dans ce scénario?
La solution
La version normale de fParsec (mais pas le Version à faible confiance) lit l'entrée en termes CharStream
Documentation. Ainsi, si vous construisez un CharStream
de System.IO.Stream
Et le contenu est suffisamment grand pour s'étendre CharStream
Blocs, vous pouvez commencer à analyser avant d'avoir complètement récupéré l'entrée.
Notez cependant que le CharStream
consommera le flux d'entrée en morceaux d'une taille fixe (mais configurable), c'est-à-dire qu'il appellera le Read
Méthode de la System.IO.Stream
aussi souvent que nécessaire pour remplir un bloc complet. Par conséquent, si vous analysez l'entrée plus rapidement que vous pouvez récupérer de nouvelles entrées, la CharStream
Peut bloquer même s'il y a déjà une entrée non comparée, car il n'y a pas encore suffisamment d'entrée pour remplir un bloc complet.
Mise à jour
La réponse à vos questions ultimes: 42.
Comment vous implémentez le
Stream
à partir de laquelle vous construisez leCharStream
dépend entièrement de vous. La restriction dont vous vous souvenez qui exclut l'accès parallèle s'applique uniquement auCharStream
classe, qui n'est pas sûr.Implémentation du
Stream
comme un tampon circulaire restreindre la distance maximale sur laquelle vous pouvez revenir en arrière.La taille du bloc du
CharStream
influence le chemin du chemin où vous pouvez revenir en arrière lorsqueStream
ne soutient pas la recherche.Le moyen le plus simple de l'analyse d'entrée de manière asynchrone est de faire l'analyse dans une tâche asynchrone (c'est-à-dire sur un thread d'arrière-plan). Dans la tâche, vous pouvez simplement lire la prise de manière synchrone, ou, si vous ne faites pas confiance à la mise en mémoire tampon par le système d'exploitation, vous pouvez utiliser une classe de flux comme le
BlockingStream
Décrit dans l'article que vous avez lié dans le deuxième commentaire ci-dessous.Si l'entrée peut être facilement séparée en morceaux indépendants (par exemple les lignes pour un format de texte basé sur la ligne), il pourrait être plus efficace de le remonter vous-même, puis d'analyser le morceau d'entrée par morceau.