Разбор по частям с FParsec
Можно ли передавать входные данные парсеру FParsec порциями, как из сокета? Если нет, возможно ли получить текущий результат и непарсированную часть входного потока, чтобы я мог выполнить это? Я пытаюсь запустить куски ввода, поступающие из SocketAsyncEventArgs
без буферизации целых сообщений.
Обновить
Причина, по которой стоит отметить использование SocketAsyncEventArgs
должен был обозначить, что отправка данных на CharStream
может привести к асинхронному доступу к базовому Stream
, В частности, я рассматриваю использование кругового буфера для передачи данных, поступающих из сокета. Я помню документацию FParsec, отмечая, что основной Stream
доступ не должен выполняться асинхронно, поэтому я планировал вручную управлять разбивкой по частям.
Конечные вопросы:
- Могу ли я использовать круговой буфер под моим
Stream
перешел кCharStream
? - Не нужно ли мне беспокоиться о ручном контроле чанкинга в этом сценарии?
1 ответ
Обычная версия FParsec (хотя и не версия с низким уровнем доверия) читает входные данные по частям или "по блокам", как я это называю в CharStream
документация Таким образом, если вы строите CharStream
из System.IO.Stream
и содержание достаточно велико, чтобы охватить несколько CharStream
блоки, вы можете начать синтаксический анализ, прежде чем вы полностью получили входные данные.
Обратите внимание, что CharStream
будет использовать входной поток в виде фрагментов фиксированного (но настраиваемого) размера, т. е. вызовет Read
метод System.IO.Stream
так часто, как это необходимо, чтобы заполнить полный блок. Следовательно, если вы анализируете ввод быстрее, чем можете получить новый ввод, CharStream
может блокировать даже при том, что уже есть некоторый необработанный ввод, потому что еще не достаточно ввода, чтобы заполнить полный блок.
Обновить
Ответ (ы) на ваши окончательные вопросы: 42.
Как вы реализуете
Stream
из которого вы строитеCharStream
полностью зависит от вас. Запоминаемое вами ограничение, исключающее параллельный доступ, относится только кCharStream
класс, который не является потокобезопасным.Реализация
Stream
поскольку круговой буфер, скорее всего, ограничит максимальное расстояние, на которое вы можете вернуться.Размер блока
CharStream
влияет на то, как далеко вы можете вернуться, когдаStream
не поддерживает поиск.Самый простой способ асинхронного анализа входных данных - выполнить синтаксический анализ в асинхронной задаче (т. Е. В фоновом потоке). В этом задании вы можете просто прочитать сокет синхронно или, если вы не доверяете буферизации ОС, вы можете использовать класс потока, такой как
BlockingStream
описанный в статье вы связали во втором комментарии ниже.Если входные данные могут быть легко разделены на независимые блоки (например, строки для текстового формата на основе строк), может быть более эффективно разбить его на части самостоятельно, а затем проанализировать входной блок данных на блок.