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.ProtoException" в protobuf-net.dll Дополнительная информация: Неверное поле в исходных данных: 0 Я думаю, что эта ошибка происходит, потому что поток больше, чем фактические данные, которые он содержит. Когда поток десериализован, я думаю, что он начинает читать дальше фактических данных.

Исключение: "ProtoBuf.ProtoException" в protobuf-net.dll Дополнительная информация: не найден конструктор без параметров для Test

Однако я не уверен, что это лучший способ исправить это. Есть ли способ прочитать байты из потока до тех пор, пока не останется данных, а затем остановиться? Если нет, могу ли я решить это по-другому?

1 ответ

Решение

Я не уверен, что лучший способ это исправить

  1. добавить конструктор без параметров (это может быть private если хотите) или
  2. добавить SkipConstructor = true в качестве параметров на [ProtoContract(...)] по вашему типу

тем не мение. Есть ли способ прочитать байты из потока до тех пор, пока не останется данных, а затем остановиться?

Да, это значение по умолчанию в буферах протокола, так как самое внешнее сообщение не включает в себя маркер длины или маркер конца (он предназначен для добавления). Однако, в вашем случае, это, вероятно, не то, что вам нужно, так как после сериализации данных будет различный мусор (возможно, все нули, возможно, нет). Вы можете использовать SerializeWithLengthPrefix а также DeserializeWithLengthPrefix вместо. И если ваши данные только 1000 байтов, MemoryStream все будет в порядке - не нужно использовать неуправляемую память.

Другие вопросы по тегам