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