Разбор по частям с FParsec

Можно ли передавать входные данные парсеру FParsec порциями, как из сокета? Если нет, возможно ли получить текущий результат и непарсированную часть входного потока, чтобы я мог выполнить это? Я пытаюсь запустить куски ввода, поступающие из SocketAsyncEventArgs без буферизации целых сообщений.

Обновить

Причина, по которой стоит отметить использование SocketAsyncEventArgs должен был обозначить, что отправка данных на CharStream может привести к асинхронному доступу к базовому Stream, В частности, я рассматриваю использование кругового буфера для передачи данных, поступающих из сокета. Я помню документацию FParsec, отмечая, что основной Stream доступ не должен выполняться асинхронно, поэтому я планировал вручную управлять разбивкой по частям.

Конечные вопросы:

  1. Могу ли я использовать круговой буфер под моим Stream перешел к CharStream?
  2. Не нужно ли мне беспокоиться о ручном контроле чанкинга в этом сценарии?

1 ответ

Решение

Обычная версия FParsec (хотя и не версия с низким уровнем доверия) читает входные данные по частям или "по блокам", как я это называю в CharStream документация Таким образом, если вы строите CharStream из System.IO.Stream и содержание достаточно велико, чтобы охватить несколько CharStream блоки, вы можете начать синтаксический анализ, прежде чем вы полностью получили входные данные.

Обратите внимание, что CharStream будет использовать входной поток в виде фрагментов фиксированного (но настраиваемого) размера, т. е. вызовет Read метод System.IO.Stream так часто, как это необходимо, чтобы заполнить полный блок. Следовательно, если вы анализируете ввод быстрее, чем можете получить новый ввод, CharStream может блокировать даже при том, что уже есть некоторый необработанный ввод, потому что еще не достаточно ввода, чтобы заполнить полный блок.

Обновить

Ответ (ы) на ваши окончательные вопросы: 42.

  • Как вы реализуете Stream из которого вы строите CharStream полностью зависит от вас. Запоминаемое вами ограничение, исключающее параллельный доступ, относится только к CharStream класс, который не является потокобезопасным.

  • Реализация Stream поскольку круговой буфер, скорее всего, ограничит максимальное расстояние, на которое вы можете вернуться.

  • Размер блока CharStream влияет на то, как далеко вы можете вернуться, когда Stream не поддерживает поиск.

  • Самый простой способ асинхронного анализа входных данных - выполнить синтаксический анализ в асинхронной задаче (т. Е. В фоновом потоке). В этом задании вы можете просто прочитать сокет синхронно или, если вы не доверяете буферизации ОС, вы можете использовать класс потока, такой как BlockingStream описанный в статье вы связали во втором комментарии ниже.

  • Если входные данные могут быть легко разделены на независимые блоки (например, строки для текстового формата на основе строк), может быть более эффективно разбить его на части самостоятельно, а затем проанализировать входной блок данных на блок.

Другие вопросы по тегам