SerializationException, как избежать UserControl, потребляющего событие для сериализации? - PullRequest
0 голосов
/ 04 августа 2011

Я пытаюсь сериализовать объект, и он выдает исключение, как показано ниже. Я предполагаю, что он пытается также сериализовать UserControl, который подписывается на событие класса, который я пытаюсь сериализовать. Это не желательно. Так как же избежать сериализации событий? (максимально просто)

Произошло исключение SerializationExce:

Введите 'System.Windows.Forms.UserControl' в сборке 'System.Windows.Forms, версия = 2.0.0.0, культура = нейтральная, PublicKeyToken = b77a5c561934e089 'не помечен как сериализуемый.

Public Sub SendData(ByVal obj As Object)

    If Client.Connected Then
        Try
            Dim ns As NetworkStream = Client.GetStream()

            Dim bf = New BinaryFormatter()
            Dim ms = New MemoryStream()

            bf.Serialize(ms, obj)   ' < Exception here

Ответы [ 4 ]

2 голосов
/ 04 августа 2011

как избежать сериализации событий?

Решение состоит в том, чтобы пометить обработчики событий в вашем классе атрибутом [ NonSerialized ].

0 голосов
/ 04 августа 2011

VB.NET не разрешит атрибут для событий. Из-за способа, которым VB.NET реализует события, при сериализации объекта его события также сериализуются, потому что события фактически реализуются с использованием скрытых полей делегата многоадресной передачи. Вот пример того, как удалить обработчик во время сериализации в vb:

      <NonSerialized()> _
  Private PropertyChangedHandlers As New Generic.List(Of PropertyChangedEventHandler)

  ''' <summary>
  ''' stores parameter of event in a local nonserializable variable
  ''' </summary>
  ''' <remarks></remarks>
  Public Custom Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
     AddHandler(ByVal value As PropertyChangedEventHandler)
        If PropertyChangedHandlers Is Nothing Then
           PropertyChangedHandlers = New Generic.List(Of PropertyChangedEventHandler)()
        End If
        PropertyChangedHandlers.Add(value)
     End AddHandler

     RemoveHandler(ByVal value As PropertyChangedEventHandler)
        If value Is Nothing Or PropertyChangedHandlers Is Nothing Then
           Return
        End If

        PropertyChangedHandlers.Remove(value)
     End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
            Dim pos As Int32
            Dim count As Int32
            Dim Element As PropertyChangedEventHandler
            If Me.PropertyChangedHandlers IsNot Nothing Then
                count = PropertyChangedHandlers.Count
                If count > 0 Then
                    For pos = (count - 1) To 0 Step -1
                        Element = PropertyChangedHandlers(pos)
                        Try
                            Element.Invoke(sender, e)
                        Catch ex As Exception
                            'Ignore any error generated
                        End Try
                    Next
                End If
            End If
        End RaiseEvent
  End Event
0 голосов
/ 04 августа 2011

Один из вариантов - реализовать ISerializable и сериализовать только то, что вы хотите.

Другой вариант, доступный для C # (я не уверен насчет VB), - это сделать собственный код добавления / удаления.

[NonSerialized]  // prevents the m_changed field from being serialized.
private EventHandler m_changed;

public event Changed
{
  add
  {
    m_changed += value;
  }
  remove
  {
    m_changed -= value;
  }
}
0 голосов
/ 04 августа 2011

Похоже, что ваш объект, который вы передаете в вашу рутину, не сериализуем.Вы передаете свой пользовательский контроль этому методу?Если это так, вам нужно будет передать то, что вы хотите сериализовать, что, я полагаю, может быть структура данных внутри?В противном случае попробуйте использовать атрибут [Searilzable] на вашем объекте и посмотрите, работает ли он.

...