Do closures break serialization

久未见 提交于 2019-12-07 17:10:38

问题


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

Type 'Xyz.GeneralUnderstandingTests+ASerializableType+<>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.

Searching Stackoverflow for closure serialization I found some Q&As that reveal that closures cannot be serialized in other languages such as PHP *) but I did not manage to find such a statement for C#. I have however been able to build a very simple example that seems to confirm that closures are not serializable whereas "normal" functions are

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

        public ASerializableType()
        {
            const int SomeConst = 12345;
            thisIsNotAClosure = () => SomeConst; // succeeds to serialize

            var someVariable = 12345;
            thisIsAClosure = () => someVariable; // fails to serialize
        }
    }

    [Test]
    public void ASerializableType_CanBeSerialized()
    {
        var sessionStateItemCollection = new 
            System.Web.SessionState.SessionStateItemCollection();
        sessionStateItemCollection["sut"] = new ASerializableType();
        sessionStateItemCollection.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.

Can you confirm that what I have concluded is correct?

=> Is there a way to circumvent this issue?

=> Could it be that this depends on the internals of the compiler used? Since it is the compiler that turns the lambda/closure expression into a anonymous inner class.

*) Links:

  • Exception: Serialization of 'Closure' is not allowed
  • Closures Can't Be Serialized, How To Do Callbacks via AJAX to PHP?
  • Serialization of 'Closure' is not allowed with php pthreads
  • How to serialize object that has closures inside properties?

来源:https://stackoverflow.com/questions/26887460/do-closures-break-serialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!