有没有办法将bytes
字段反序列化为Stream成员,而没有protobuf-net预先分配新的(可能很大的)byte []?
我正在寻找类似的东西:
[ProtoContract]
public class Message
{
[ProtoMember(1)]
Stream Payload { get; set; }
}
流可以由预先分配的缓冲池支持,例如Microsoft.IO.RecyclableMemoryStream
。即使在下降到ProtoReader
进行反序列化之后,我看到的只是AppendBytes
,它总是分配一个字段长度的缓冲区。一个人必须进一步下降到DirectReadBytes
,这只能直接在消息流上运行 - 我想避免这种情况。
作为背景,我使用protobuf-net对线路上的消息进行序列化/反序列化。这是一个用于在客户端之间传递消息的中间层组件,因此消息实际上是封闭二进制有效负载的包络:
message Envelope {
required string messageId = 1;
map<string, string> headers = 2;
bytes payload = 3;
}
payload
的大小限制为~2 MB,但大到足以让字节[]落在LOH中。
使用Protobuf-net: Serializing a 3rd party class with a Stream data member中的代理不起作用,因为它只包含相同的单片阵列。
Memory usage serializing chunked byte arrays with Protobuf-net中提到了一种应该有效的技术,将bytes
更改为repeated bytes
并依赖发件人来限制每个块。这个解决方案可能已经足够好了,它可以防止LOH分配,但它不会允许缓冲池。
答案 0 :(得分:1)
这里的问题是关于payload
字段。不,目前还没有一种机制可以解决这个问题,但肯定可以对选项进行调查。可能是我们可以对序列化上下文执行类似ArraySegment<byte> AllocateBuffer(int size)
回调的操作,调用者可以使用它来控制分配(关于这一点的好处是protobuf-net实际上不能用于{ {1}},所以这将是一个纯粹的增量更改,不会影响任何现有的工作代码;如果没有提供回调,我们可能只是像现在一样分配一个平缓冲区)。我愿意接受其他建议,但现在:不 - 它将在内部分配ArraySegment<byte>
。