.NET 2.0 solution to serialization of objects that raise events

.NET 2.0 solution to serialization of objects that raise events

Old forum URL: forums.lhotka.net/forums/t/2978.aspx


Mike.Smith posted on Saturday, June 02, 2007

I have been stung by the problem of my object raising an event that my form is handling. As a result of the reference my object has to my form, serialization is attempted on the form itself. The problem and one solution is described by Rocky here: http://www.lhotka.net/WeBlog/PermaLink.aspx?guid=776f44e8-aaec-4845-b649-e0d840e6de2c

A better implementation of the solution was posted a couple of weeks later: http://www.lhotka.net/weblog/BetterVersionOfTheNET20EventserializationSolution.aspx

This is great but I can't seem to get either of these solutions to work correctly. These custom event declarations work for raising the events and the form can handle those events just fine but they don't seem to help with the core problem because I get an error indicating serialization is still attempted on the form!

In the first article, Rocky says: "...we can declare our backing field to be NonSerialized if we so desire. Better yet, we can have two backing fields – one for targets that can be serialized, and another for targets that can’t be serialized."

I have looked at the code and although there are two backing fields declared, they are both handled exactly the same. Also, neither of them have the NonSerialized attribute. Adding the attribute does not seem to help the problem either. I am puzzled how this is even supposed to help. Am I supposed to add and remove the handlers myself somewhere in the code? This seems to defeat the purpose of the solution.

Has anyone else been able to get these examples to work? I am about to give up and go to Observer Events instead but I'd like to get this to work if possible.

Any insight would be much appreciated.

Mike

Mike.Smith replied on Saturday, June 02, 2007

I have found a solution. Looks like I blew it pretty major. I actually have more than one object that my form is handling events for! I only tested the solutions on one of the objects and the other object retained the reference to the form. Duh!

Once I updated both objects, it works fine. Sorry for the false alarm.

Mike

PStanev replied on Monday, August 04, 2008

I have the same problem: (serializing objects that raise events when those events are handled by a non-serializable object (like a Windows Form). )The only diffence im my code is thet I dont use the standard EventHandler Because I have input parameteres. Here is my code:

<NonSerialized()> _

Private mNonSerializableSM As SMHandler

Private mSerializableSM As SMHandler

Delegate Sub SMHandler(ByVal Message As String, ByVal MessageType As MsgBoxStyle)

Public Custom Event SimpleMessageEvent As SMHandler

AddHandler(ByVal value As SMHandler)

If value.Target.GetType.IsSerializable Then

mSerializableSM = CType([Delegate].Combine(mSerializableSM, value), SMHandler)

Else

mNonSerializableSM = CType([Delegate].Combine(mNonSerializableSM, value), SMHandler)

End If

End AddHandler

RemoveHandler(ByVal value As SMHandler)

If value.Target.GetType.IsSerializable Then

mSerializableSM = CType([Delegate].Remove(mSerializableSM, value), SMHandler)

Else

mNonSerializableSM = CType([Delegate].Remove(mNonSerializableSM, value), SMHandler)

End If

End RemoveHandler

RaiseEvent(ByVal Message As String, ByVal MessageType As MsgBoxStyle)

If mNonSerializableSM IsNot Nothing Then mNonSerializableSM(Message, MessageType)

If mSerializableSM IsNot Nothing Then mSerializableSM(Message, MessageType)

End RaiseEvent

End Event

Everithing look right , but I still get the runtime error.

Please Help.

Thank You.

nj609eagle replied on Tuesday, November 23, 2010

I've read and re-read all of this thread and many others but it's still not working for me:

 

<NonSerialized()> _
Private _NonSerializableHandlers As New Generic.List(Of EventHandler)
Private _SerializableHandlers As New Generic.List(Of EventHandler)

Public Custom Event DuesRefreshed As System.EventHandler
     AddHandler(ByVal value As EventHandler)
    

'If value.Target.GetType.IsSerializable Then

' _SerializableHandlers = CType([Delegate].Combine(_SerializableHandlers, value), EventHandler)

'Else

' _NonSerializableHandlers = CType([Delegate].Combine(_NonSerializableHandlers, value), EventHandler)

'End If

If value.Target.GetType.IsSerializable Then

_SerializableHandlers.Add(value)

Else

If _NonSerializableHandlers Is Nothing Then

_NonSerializableHandlers = New Generic.List(Of EventHandler)()

End If

_NonSerializableHandlers.Add(value)

End If

End AddHandler

RemoveHandler(ByVal value As EventHandler)

'If value.Target.GetType.IsSerializable Then

' _SerializableHandlers = CType([Delegate].Remove(_SerializableHandlers, value), EventHandler)

'Else

' _NonSerializableHandlers = CType([Delegate].Remove(_NonSerializableHandlers, value), EventHandler)

'End If

If value.Target.GetType.IsSerializable Then

_SerializableHandlers.Remove(value)

Else

_NonSerializableHandlers.Remove(value)

End If

End RemoveHandler

RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)

'If _NonSerializableHandlers IsNot Nothing Then _NonSerializableHandlers(sender, e)

'If _SerializableHandlers IsNot Nothing Then _SerializableHandlers(sender, e)

For Each item As EventHandler In _NonSerializableHandlers

item.Invoke(sender, e)

Next

For Each item As EventHandler In _SerializableHandlers

item.Invoke(sender, e)

Next

End RaiseEvent

End Event

Copyright (c) Marimer LLC