Problem with serialization of objects that raise events handled by a non-serializable object (like a Windows Form)
|
Hi Rocky,
I have the same problem in vb.net.
I found this post in your blog : http://www.lhotka.net/weblog/BetterVersionOfTheNET20EventserializationSolution.aspx
I code as you (or I think I do). In fact, I took the same code as event code in CSLA 3.5 (PropertyChanged / PropertyChanging / Saved ..).
Here my code in ucCustomer (user control in UI) and in Customer (in BLL).
-) in ucCustomer
Private Sub myevent(ByVal sender As Object, ByVal e As EVZoneEventArgs) Handles mCustomer.ErreurValideZone
MessageBox.Show(e.StrErreur)
End Sub
-) in Customer
<NonSerialized()> _
Public _nonSerializableEVZHandlers As EventHandler(Of EVZoneEventArgs)
Public _SerializableEVZHandlers As EventHandler(Of EVZoneEventArgs)
Public Custom Event ErreurValideZone As EventHandler(Of EVZoneEventArgs)
AddHandler(ByVal value As EventHandler(Of EVZoneEventArgs))
If value.Method.IsPublic AndAlso (value.Method.DeclaringType.IsSerializable OrElse value.Method.IsStatic) Then
_SerializableEVZHandlers = CType([Delegate].Combine(_SerializableEVZHandlers, value), EventHandler(Of EVZoneEventArgs))
Else
_nonSerializableEVZHandlers = CType([Delegate].Combine(_nonSerializableEVZHandlers, value), EventHandler(Of EVZoneEventArgs))
End If
End AddHandler
RemoveHandler(ByVal value As EventHandler(Of EVZoneEventArgs))
If value.Method.IsPublic AndAlso (value.Method.DeclaringType.IsSerializable OrElse value.Method.IsStatic) Then
_SerializableEVZHandlers = CType([Delegate].Remove(_SerializableEVZHandlers, value), EventHandler(Of EVZoneEventArgs))
Else
_nonSerializableEVZHandlers = CType([Delegate].Remove(_nonSerializableEVZHandlers, value), EventHandler(Of EVZoneEventArgs))
End If
End RemoveHandler
RaiseEvent(ByVal sender As System.Object, ByVal e As EVZoneEventArgs)
If Not _SerializableEVZHandlers Is Nothing Then
_SerializableEVZHandlers(sender, e) '.Invoke(sender, e)
End If
If Not _nonSerializableEVZHandlers Is Nothing Then
_nonSerializableEVZHandlers(sender, e) '.Invoke(sender, e)
End If
End RaiseEvent
End Event
Public Class EVZoneEventArgs : Inherits EventArgs
Private mNumErreur As Integer
Private mStrErreur As String
Public Sub New(ByVal numErreur As Integer, ByVal strErreur As String)
mNumErreur = numErreur
mStrErreur = strErreur
End Sub
Public ReadOnly Property NumErreur() As Integer
Get
Return mNumErreur
End Get
End Property
Public ReadOnly Property StrErreur() As String
Get
Return mStrErreur
End Get
End Property
End Class
The issue during the run time appends in CSLA in BinaryFormatterWrapper.vb :
Public Sub Serialize(ByVal serializationStream As System.IO.Stream, ByVal graph As Object) _
Implements ISerializationFormatter.Serialize
_formatter.Serialize(serializationStream, graph)
End Sub
To test, I put breakpoints and I go step by step.
I saw that _nonSerializableEVZHandlers is used.
If I put a comment before _formatter.Serialize(serializationStream, graph) then the UI consume the event but .. it is not good because I change CSLA and there is no serialization.
If I put a comment in the event code in the UI and no comment before _formatter.Serialize, I have no runtime error
I don't understand where is my mistake.
Thanks for your help.
Dominique
PS: to Ross (tetranz) : I think that databinding is "a" way of communicating between an object and a form. But it is not the only way, sometimes it is useful to use an event.
To Stefan : I am sorry but I don't use C#
*bump*
I reactivate this thread because I didn't have an answer.
During this time, I put a comment before _formatter.Serialize(serializationStream, graph) in Csla (BinaryFormaterHelper.vb) but it is not a solution.
I use now Csla vb 3.52 and I have always the same problem.
I use in a BO class, the same code there is in Bindable.vb.
I can see (with breakpoints and step by step) that_nonSerializableEVZHandlers is used for the AddHandler to define the event.
The problem is in _formatter.Serialize(serializationStream, graph)
I test without _nonSerializableEVZHandlers and it is good.
Thanks for help.
I think that I found the solution :
If I add in my code : <NotUndoable()> _ it is OK :
<NonSerialized()> _
<NotUndoable()> _
Public _nonSerializableEVZHandlers As EventHandler(Of EVZoneEventArgs)
<NotUndoable()> _
Public _SerializableEVZHandlers As EventHandler(Of EVZoneEventArgs)
Rocky, you use this code in 4 places in Csla.
Two with <NotUndoable()> _ : BusinessBase.vb and BusinessListBase
Two without <NotUndoable()> _ : Bindable.vb and ExtendedBindingList.vb
Is it normal ?
Copyright (c) Marimer LLC