protobuf网络支持ArraySegment吗



我已经读到Protobuf net memcache提供程序在附加/设置ArraySegment时失败,这表明它可能在某个时候得到支持。

我也尝试了这个问题中建议的测试,这表明2.0.0.668版本不支持它

有没有人成功地将ArraySegments与protobuf-net一起使用,或者有一个通过有线发送字节数组的有效方法的想法。

也就是说,我有一个这样的对象:

[ProtoContract] 
class Foo
{
    [ProtoMember(1)]
    public byte[] Data { get; set; }
}

我想将不同的对象T序列化为一个字节数组,将其分配给Data,然后将Foo序列化为另一个字节[]。(听起来无效,但Foo类必须与类型无关,它可以是泛型的吗?)。

关键是我希望尽量减少分配/GC,所以每次序列化数据时,我都希望尽量减少数组的复制或新数组的分配。

下面是一些示例代码,它展示了我试图更有效地实现的目标:

public class DataSender<T>
{
    private ISerializer serializer; //Could be any kind of binary serializer 
    public void Send(T obj)
    {
        MemoryStream serializationBuffer = new MemoryStream(); // Inefficent allocation
        serializer.Serialize(serializationBuffer, obj);
        var sendable = new Foo(){ Data=serializationBuffer.ToArray() } // Inefficent copy
        Sender.Send(sendable);
     }
}

任何关于替换我的Foo对象和/或发送代码的建议都将非常受欢迎。

这对我来说太复杂了。我认为你让Foo通用的想法很好,所以你可以有:

[ProtoContract]
class Foo<T>
{
    [ProtoMember(1)]
    public T Data { get; set; }
}

然后你可以用简单的代码实例化一个新的对象,比如:

var foo = new Foo<Bar>() { Data = new Bar() { Data = "Some Data" } };

但是,根据您的附加注释,您不能保证对象是可序列化的,或者具有proto属性。例如,bar类可能看起来像:

class Bar
{
    public string Data { get; set; }
}

在这种情况下,可以使用RuntimeTypeModel类在运行时配置序列化。

以下是使用protobuf对数据对象进行动态运行时配置的完整序列化和反序列化示例:

using (var serializationBuffer = new MemoryStream())
{
    var foo = new Foo<Bar>() { Data = new Bar() { Data = "Some Data" } };
    RuntimeTypeModel.Default.Add(foo.Data.GetType(), false)
        .Add(foo.GetType().GetProperties().Select(p => p.Name).ToArray());
    Serializer.Serialize(serializationBuffer, foo);
    serializationBuffer.Seek(0, SeekOrigin.Begin);
    var deserialized = Serializer.Deserialize<Foo<Bar>>(serializationBuffer);
}

通过这种方式,您可以使用任何对象作为数据对象,即使它没有序列化属性。但是,由于反射用于发现类型属性,因此您将受到性能的惩罚。但是,您应该获得所需的灵活性

使用WCF通过连线发送此对象的正确方法是使用protobuf ProtoEndpointBehavior配置WCF自定义行为,然后WCF将使用protobuf自动序列化和反序列化Foo对象。这意味着客户端只需要确保它使用的是用proto属性装饰的对象,并通过有线发送它们。WCF将负责序列化/反序列化。

以下是一个如何使用WCF protobuf服务的综合示例:

http://www.drdobbs.com/windows/working-with-protobuf-wcf-services/240159282?pgno=1

通过导线发送数据的效率取决于许多因素。如果您通过连线发送大对象,您可以将WCF TransferMode设置为使用流式处理,然后在另一端读取字节数组块中的数据。

但是,效率是您应该衡量的,而不是假设

最新更新