Pergunta

É possível enviar entrada para um analisador FParsec em blocos, a partir de um soquete? Se não, é possível recuperar o resultado atual e a parte não analisada de um fluxo de entrada para que eu possa fazer isso? Estou tentando executar os blocos de entrada vindos de SocketAsyncEventArgs sem armazenar em buffer mensagens inteiras.

<"Atualizar

O motivo para observar o uso de SocketAsyncEventArgs foi para denotar que o envio de dados para um CharStream pode resultar em acesso assíncrono ao Stream subjacente. Especificamente, estou pensando em usar um buffer circular para enviar os dados vindos do soquete. Lembro-me da documentação do FParsec observando que o Stream subjacente não deve ser acessado de forma assíncrona, então planejei controlar manualmente a análise fragmentada.

Perguntas finais:

  1. Posso usar um buffer circular no meu Stream passado para o CharStream?
  2. Não preciso me preocupar em controlar manualmente a fragmentação neste cenário?
Foi útil?

Solução

A versão normal do FParsec (embora não o Baixo -Versão confiável ) lê a entrada em blocos, ou "blocos", como eu chamo em documentação CharStream . Portanto, se você construir um CharStream a partir de um System.IO.Stream e o conteúdo for grande o suficiente para abranger vários blocos CharStream, você pode começar a analisar antes de recuperar totalmente a entrada.

Observe, no entanto, que o CharStream consumirá o fluxo de entrada em blocos de tamanho fixo (mas configurável), ou seja, ele chamará o método Read do System.IO.Stream quantas vezes for necessário para preencher um bloco completo. Portanto, se você analisar a entrada mais rápido do que pode recuperar uma nova entrada, o CharStream pode bloquear mesmo que já haja alguma entrada não analisada, porque ainda não há entrada suficiente para preencher um bloco completo.

< Budapate

A (s) resposta (s) para suas perguntas principais: 42.

  • A forma como você implementa o Stream a partir do qual constrói o CharStream depende inteiramente de você. A restrição que você está lembrando que exclui o acesso paralelo se aplica apenas à classe CharStream, que não é thread-safe.

  • A implementação do Stream como um buffer circular provavelmente restringe a distância máxima na qual você pode retroceder.

  • O tamanho do bloco do CharStream influencia o quanto você pode retroceder quando o Stream não oferece suporte à busca.

  • A maneira mais simples de analisar a entrada de forma assíncrona é fazer a análise em uma tarefa assíncrona (ou seja, em um thread de segundo plano). Na tarefa, você pode simplesmente ler o soquete de forma síncrona ou, se não confiar no armazenamento em buffer do sistema operacional, pode usar uma classe de fluxo como o BlockingStream descrito no artigo que você vinculou no segundo comentário abaixo.

  • Se a entrada puder ser facilmente separada em pedaços independentes (por exemplo, linhas para um formato de texto baseado em linha), pode ser mais eficiente dividir você mesmo e, em seguida, analisar o pedaço de entrada por pedaço.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top