IPC使用Protobuf和内存映射文件C#



我正在编写一个项目,将对象从父应用程序传递给子应用程序。我使用Protobuf来序列化和反序列化数据。我还在序列化时使用非持久化内存映射文件进行写入(在反序列化时从中读取)。这是代码:

[ProtoContract(SkipConstructor = true)]
public class Test
{
    [ProtoMember(1)]
    public int ID { get; private set; }
    [ProtoMember(2)]
    public bool TestBool { get; private set; }
    [ProtoMember(3)]
    public string MessageBody { get; private set; }
    public Test(int id, bool testBool, string messageBody)
    {
        this.ID = id;
        this.TestBool = testBool;
        this.MessageBody = messageBody;
    }

    public void Serialize()
    {
        MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 1000);
        using (MemoryMappedViewStream stream = mmf.CreateViewStream())
        {
            Serializer.SerializeWithLengthPrefix(stream, this, PrefixStyle.Base128);
            stream.Flush();
        }
    }
    public static Test Deserialize()
    {
        using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
        {
            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                return Serializer.DeserializeWithLengthPrefix<Test>(stream, PrefixStyle.Base128);
            }
        }
    }
}
//On the parent application
var msg = new SharedLibrary.Test(1234, true, "Test message hahah");
msg.Serialize();
//spawn child application

//On the child application
Test result = Test.Deserialize();   

当我运行此代码时,我得到以下错误(当调用Serializer.Deserialize时):

引发异常:ProtoBuf-net.dll中的"ProtoBuf.ProtoException"其他信息:源数据中的字段无效:0我认为发生这个错误是因为流比它包含的实际数据大。当流被反序列化时,我认为它开始读取超出实际数据的内容

引发异常:ProtoBuf-net.dll中的"ProtoBuf.ProtoException"附加信息:未找到测试的无参数构造函数

然而,我不确定解决这个问题的最佳方法。有没有办法从流中读取字节,直到没有剩余数据,然后停止?如果不能,我能用另一种方法解决吗?

我不确定修复的最佳方法

  1. 添加一个无参数构造函数(如果您愿意,它可以是private),或者
  2. 在类型的[ProtoContract(...)]上添加SkipConstructor = true作为参数

然而。有没有办法从流中读取字节,直到没有剩余数据,然后停止?

是的,这是协议缓冲区中的默认值,因为最外面的消息不包括长度标记或结束标记(它被设计为可追加)。然而,在您的情况下,这可能不是您想要的,因为在您序列化的数据之后会有各种垃圾(可能都是零,也可能不是)。您可能需要使用SerializeWithLengthPrefixDeserializeWithLengthPrefix。如果您的数据只有1000字节,那么MemoryStream就可以了——不需要使用非托管内存。

相关内容

  • 没有找到相关文章

最新更新