13

I have a simple class that is marked as Serializable, and it happens to have an event. I tried to mark the event member as NonSerialized, however the compiler complains. Yet when I go to serialize the class instance, the BinaryFormatter throws an exception that the event is non serializable. Does that mean you can't serialize classes that have events? If so, then the compiler should say so up front.

Stream file = File.Open("f", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();

object obj = null;
try
{
    obj = bf.Deserialize(file);
}
catch (System.Runtime.Serialization.SerializationException e)
{
    MessageBox.Show("De-Serialization failed : {0}", e.Message);
}
file.Close();

System.Collections.ArrayList nodeList = obj as System.Collections.ArrayList;

foreach (TreeNode node in nodeList)
{
    treeView.Nodes.Add(node);
}

Fails to work on the following class:

[Serializable()]
class Simple
{
    private int myInt;
    private string myString;
    public event SomeOtherEventDefinedElsewhere TheEvent;

}

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Rhubarb
  • 3,893
  • 6
  • 41
  • 55
  • Can you explain a little more about what you are trying to do and possibly give us a little code snippet? – IAbstract Feb 22 '10 at 03:28
  • Sure. I just have this class that has mostly string and int properties. But it has a few events to notify consumers when the instances of it change. I am storing instances of this class in the Tag property of a .NET TreeView class, or more specifically, in each Tag property of each TreeNode that corresponds to the object. When I try to serialize the TreeView to disk (storing each node in an ArrayList and then writing out the list), I get an exception: "Type 'MyEventSubscriber' in Assembly 'MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable." – Rhubarb Feb 22 '10 at 03:45
  • cont... MyEventSubscriber happens to be the class instance of the subscriber to the event on the class I'm trying to serialize (the one that is in the Tag property of the TreeNode). – Rhubarb Feb 22 '10 at 03:46
  • Please edit the original question (then you can use formating) also, we really need to see some code, please make a simple case that shows the problem. – Hogan Feb 22 '10 at 03:50
  • "I tried to mark the event member as NonSerialized, however the compiler complains". What error do you get? – Foole Feb 22 '10 at 04:22

3 Answers3

25

"In the case of events, you must also add the field attribute qualifier when applying the NonSerialized attribute so that the attribute is applied to the underlying delegate rather than to the event itself" Advanced Serialization - MSDN


Prefix the NonSerializedAttribute with field

[field:NonSerialized]
public event MyEventHandler MyEvent;
Asad
  • 21,468
  • 17
  • 69
  • 94
  • I tried that however it didn't change anything. I still get the exception. It would be very odd that there's no way to dissuade the formatter from trying to serialize this. Any other suggestions? – Rhubarb Feb 22 '10 at 03:38
  • It worked for me. Thank you! Didn't know about `[field:Attribute]` syntax. Saved me some typing. – Max Nov 29 '12 at 18:28
0

It is important to remember that the attribute is [Field:NonSerialized] is applied to the delegates, not the events, case sensitive by the way, then implement a ISerializable object, and using reflection, iterate through the class that you are serializing, looking for the event handler, and unsubscribe the events first prior to serializing. Then when doing the deserializing, you can then wire up the events if necessary automatically on deserializing...

t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • 2
    Are you sure? Looks like field should be lower case 'f'. What is the point of having non serialized if I have to go and unsubscribe the events? – Rhubarb Feb 22 '10 at 03:55
  • @rhubarb@ You are freeing up the delegate by iterating through the list of listeners the delegates has or events, if you dont' the serializer will recurse through them... – t0mm13b Feb 22 '10 at 04:09
  • 2
    Well why do we need to free the listeners if the event is marked as non serializable? Isn't that a contradiction? – Rhubarb Feb 23 '10 at 03:16
  • SerializationException unless I use lower-case. – Josh Sutterfield Mar 18 '15 at 16:38
0

I know this is a late post but here's an actual answer to this question. Create manual add/remove "getters/setters" for your event (the compiler does this for you behind the scenes but in this case you must do so explicitly) then mark your event as NonSerialized. I don't have time to break out the code for you but a quick search reveals someone who ran into the same issue :

http://sanity-free.org/113/csharp_binary_serialization_oddities.html

Do not use this line however : [MethodImpl(MethodImplOptions.Synchronized)]

This leads to thread-safety issues which was fixed in C# 4; see :

http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

You'll either need to roll your own lockless alternative (using CAS) or search online for one; unfortunately I don't have the time as I have to run but you get the idea.

Hope this helps!

Anthony
  • 604
  • 6
  • 18