views:

27

answers:

1

I have some fairly simple code using Protobuf.net, which is throwing a very odd exception. In MetaType.cs on line 167 it throws a InvalidOperationException "The type cannot be changed once a serializer has been generated". What does this mean and how do I fix it?

My code looks like this:

This method starts off all the serialising:

while (!Parallel.For(0, 100, (i) =>
{
    Widget w;
    lock (f) { w = f.CreateWidget(); }

    SerialiseWidget(w);

}).IsCompleted)
{
    Thread.Sleep(10);
}

Pretty simple, it just loops through everything in Parallel, and serialises 100 widgets.

The serialise method is also pretty simple:

private byte[] SerialiseWidget(Widget w)
{
    using (MemoryStream m = new MemoryStream())
    {
        Serializer.Serialize<PacketChunk>(m, w);

        return m.ToArray();
    }
}

And finally, the widget class looks like this:

[ProtoContract]
private class Widget
{
    [ProtoMember(1)]
    public int a;

    [ProtoMember(2)]
    public byte[] b;

    [ProtoMember(3)]
    public Thing c; //Thing is itself a protocontract

    [ProtoMember(4)]
    public int d;

    [ProtoMember(5)]
    public int e;
}

Edit:: I suspect this may be to do with the fact I'm looping over in parallel. How threadsafe is Protobuf.net for that kind of thing?

+1  A: 

How threadsafe is Protobuf.net for that kind of thing?

Well, it noticed something odd happening :)

Just add a call to Serializer.PrepareSerializer at some point before the theading (app startup being the obvious point) and it should forgive you...

Edit: thinking about it, there is a fairly simple change I can make to help that specific scenario; I'll tweak that when I get a chance. Also, this should only affect the unreleased "v2" code (from sorce code) - the pre-built dll is not affected by this AFAIK.

Marc Gravell
Excellent, calling the PrepareSerializer method worked. Thanks for the fast response Marc :D
Martin