Closures leading to “Type not marked as serializable” exception


Today I faced a SerializationException that refered to some anonymous inner class stating it was not serializable, when IIS tried to store the session in the ASP.NET State Service:

Type ‘Xyz+<>c__DisplayClass10’ in Assembly ‘Xyz, Version=1.2.5429.24450, Culture=neutral, PublicKeyToken=null’ is not marked as serializable.

I looked for lambdas in my code and found quite a few, but most of them were not new and did never have any issues in serialization. But then I noticed that I had built in a new lambda expression that “happened” to build up a closure.

I have built a very simple example to confirm that closures are not serializable whereas “normal” functions are:

[TestFixture]
public class GeneralUnderstandingTests
{
    [Serializable]
    private class ASerializableType
    {
        private readonly Func thisIsAClosure;
        private readonly Func thisIsNotAClosure;

        public ASerializableType()
        {
            // Normal functions are allowed: The following
            // succeeds to serialize
            const int SomeConst = 12345;
            thisIsNotAClosure = () => SomeConst;

            // But closures are compiled to non-serializable
            // inner classes and break serialization:
            var someVariable = 12345;
            thisIsAClosure = () => someVariable;
        }
    }

    [Test]
    public void ASerializableType_CanBeSerialized()
    {
        var sessionState = SessionStateItemCollection();
        sessionState["sut"] = new ASerializableType();
        sessionState.Serialize(
            new BinaryWriter(new MemoryStream()));
    }
}

This test fails but goes green as soon as the line thisIsAClosure = … is commented out. The line thisIsNotAClosure = … however does not cause any issues as SomeConst is not a variable but a constant, that is, it does not build a closure but is inlined by the compiler.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s