【问题标题】:SerializationException, How to avoid UserControl consuming an Event to be serialized?SerializationException,如何避免 UserControl 消耗要序列化的事件?
【发布时间】:2011-08-03 22:30:32
【问题描述】:

我尝试序列化一个对象,它抛出了一个异常,如下所示。我假设它也尝试序列化订阅我尝试序列化的类的事件的 UserControl。这是不希望的。那么如何避免序列化事件呢? (尽可能简单)

发生序列化异常:

在程序集中键入“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

【问题讨论】:

    标签: .net vb.net serialization user-controls


    【解决方案1】:

    如何避免序列化事件?

    解决方案是使用 [NonSerialized] 属性标记您的类中的事件处理程序。

    【讨论】:

      【解决方案2】:

      您传递给例程的对象似乎不可序列化。您是否将用户控件传递给此方法?如果是这样,您将需要传递您想要序列化的内容,我认为这可能是其中的数据结构?否则,请尝试在您的对象上使用 [Searilzable] 属性,看看是否有效。

      【讨论】:

        【解决方案3】:

        一种选择是实现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;
          }
        }
        

        【讨论】:

          【解决方案4】:

          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
          

          【讨论】:

          • 当我在其他地方阅读时,我也这么认为,但它似乎有效。它确实编译并删除了我的异常。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-02
          • 1970-01-01
          • 2014-04-27
          • 2014-08-31
          • 2020-08-29
          • 2011-03-09
          • 1970-01-01
          相关资源
          最近更新 更多