【发布时间】:2021-07-12 07:07:04
【问题描述】:
我正在尝试使用带有字节长度前缀的PipeWriter 编写二进制消息。
在整个消息完成之前,我不知道字节长度。
PipeWriter 可以做到这一点吗?
基本上我正在尝试实现这三种方法:
void StartMessage(PipeWriter writer)
{
// leave 4 empty bytes for length written at later time
this.header_ = writer.GetMemory(4);
writer.Advance(4);
}
void Write(PipeWriter writer, ReadOnlySpan<byte> span)
{
var buffer = writer.GetSpan(span.Length);
span.CopyTo(buffer);
writer.Advance(span.Length);
this.totalLength_ += span.Length;
}
ValueTask EndMessage(PipeWriter writer)
{
// should prepend this.totalLength_ to the message
BinaryPrimities.WriteUInt32BingEndian(this.header_.Span, this.totalLength_);
// signal end of message
return writer.FlushAsync();
}
这给了我预期的结果,但PipeWrite.Advance 的文档指出:
调用 System.IO.Pipelines.PipeWriter.Advance(System.Int32) 后必须请求新的缓冲区才能继续写入更多数据;您无法写入先前获取的缓冲区。
使用PipeReader 和AdvanceTo(consumed,examined) 方法可以轻松读取此类消息,其中我们仅在整个消息长度可用时才使用输入,但我无法提出正确的PipeWriter 用法根据文档。
【问题讨论】:
-
我在这里找到了一些关于这种用法的讨论:github.com/dotnet/runtime/issues/26818#issuecomment-653681852。似乎代码所基于的行为是未定义的。