0

我正在尝试使用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使用and方法可以轻松读取此类消息AdvanceTo(consumed,examined),其中我们仅在整个消息长度可用时才使用输入,但我无法PipeWriter根据文档提出正确的用法。

4

1 回答 1

1

您展示的图案将导致free 后使用。您将在随机部分上覆盖您的输出缓冲区。

在所有字节都存在之前,您不需要发送消息,这意味着您需要所有消息都在内存中才能发送它。

您可以通过写入 MemoryStream 轻松实现此目的,然后稍后将底层缓冲区传递给 PipeWriter。

另外,请注意 PipeWriter.GetMemory 可以并且将返回比您要求的更多的字节。

于 2021-12-10T13:07:15.017 回答