質問
ソケットからのように、入力をFParsecパーサーにチャンクで送信することは可能ですか?そうでない場合、これを達成するために、入力ストリームの現在の結果と解析されていない部分を取得することは可能ですか?メッセージ全体をバッファリングせずに、SocketAsyncEventArgs
からの入力のチャンクを実行しようとしています。
更新
SocketAsyncEventArgs
の使用に注意する理由は、CharStream
にデータを送信すると、基になるStream
への非同期アクセスが発生する可能性があることを示すためでした。具体的には、循環バッファーを使用して、ソケットからのデータをプッシュすることを検討しています。基になるStream
に非同期でアクセスしてはならないというFParsecのドキュメントを覚えているので、チャンク解析を手動で制御することを計画していました。
最終的な質問:
-
Stream
に渡されたCharStream
の下で循環バッファを使用できますか? - このシナリオでチャンクを手動で制御することを心配する必要はありませんか?
解決
FParsecの通常のバージョン(ただし、低-信頼バージョン)は、 CharStream
ドキュメント。したがって、CharStream
からSystem.IO.Stream
を構築し、コンテンツが複数のCharStream
ブロックにまたがるのに十分な大きさである場合、入力を完全に取得する前に解析を開始できます。
ただし、CharStream
は、固定(ただし構成可能)サイズのチャンクで入力ストリームを消費することに注意してください。つまり、完全なブロックを埋めるために必要な頻度で、Read
のSystem.IO.Stream
メソッドを呼び出します。したがって、新しい入力を取得するよりも速く入力を解析すると、完全なブロックを満たすのに十分な入力がまだないため、解析されていない入力がすでにある場合でも、CharStream
がブロックされる可能性があります。
更新
最終的な質問への回答: 42。
-
Stream
を構築するためのCharStream
をどのように実装するかは完全にあなた次第です。並列アクセスを除外するという覚えている制限は、ジェネラコディセタグコードクラスにのみ適用され、スレッドセーフではありません。 -
CharStream
を循環バッファーとして実装すると、バックトラックできる最大距離を制限します。 -
Stream
のブロックサイズは、CharStream
がシークをサポートしていない場合にバックトラックできる距離に影響します。 -
入力を非同期に解析する最も簡単な方法は、非同期タスク(つまり、バックグラウンドスレッド)で解析を行うことです。このタスクでは、単にソケットを同期的に読み取ることができます。または、OSによるバッファリングを信頼できない場合は、以下の2番目のコメントでリンクした記事で説明されている
Stream
のようなストリームクラスを使用できます。 -
入力を独立したチャンクに簡単に分割できる場合(たとえば、行ベースのテキスト形式の行)、自分でチャンク化してから、入力チャンクをチャンクごとに解析する方が効率的です。