Exception.SerializeObjectState 事件

定义

当异常被序列化用来创建包含有关该异常的徐列出数据的异常状态对象时会出现该问题。Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

protected:
 event EventHandler<System::Runtime::Serialization::SafeSerializationEventArgs ^> ^ SerializeObjectState;
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> SerializeObjectState;
member this.SerializeObjectState : EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> 
Protected Custom Event SerializeObjectState As EventHandler(Of SafeSerializationEventArgs) 

示例

下面的示例定义了BadDivisionException一个用于SerializeObjectState处理事件的。The following example defines a BadDivisionException that handles the SerializeObjectState event. 它还包含一个状态对象,该对象是一个名为BadDivisionExceptionState的用于ISafeSerializationData实现接口的嵌套结构。It also contains a state object, which is a nested structure named BadDivisionExceptionState that implements the ISafeSerializationData interface.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class Example
{
   public static void Main()
   {
      bool serialized = false;
      var formatter = new BinaryFormatter();
      Double[] values = { 3, 2, 1 };
      Double divisor = 0;
      foreach (var value in values) {
         try {
            BadDivisionException ex = null;
            if (divisor == 0) { 
               if (! serialized) {
                  // Instantiate the exception object.
                  ex = new BadDivisionException(0);
                  // Serialize the exception object.
                  var fs = new FileStream("BadDivision1.dat", 
                                           FileMode.Create);
                  formatter.Serialize(fs, ex);
                  fs.Close();
                  Console.WriteLine("Serialized the exception...");
               }
               else {
                  // Deserialize the exception.
                  var fs = new FileStream("BadDivision1.dat",
                                           FileMode.Open);
                  ex = (BadDivisionException) formatter.Deserialize(fs);
                  // Reserialize the exception.
                  fs.Position = 0;
                  formatter.Serialize(fs, ex);
                  fs.Close();
                  Console.WriteLine("Reserialized the exception...");                                            
               }   
              throw ex; 
            } 
            Console.WriteLine("{0} / {1} = {1}", value, divisor, value/divisor);
         }   
         catch (BadDivisionException e) {
            Console.WriteLine("Bad divisor from a {0} exception: {1}",
                              serialized ? "deserialized" : "new", e.Divisor);             
            serialized = true;
         }   
      }
   }
}

[Serializable] public class BadDivisionException : Exception
{
   // Maintain an internal BadDivisionException state object.
   [NonSerialized] private BadDivisionExceptionState state = new BadDivisionExceptionState();

   public BadDivisionException(Double divisor)
   {
      state.Divisor = divisor;
      HandleSerialization();      
   }
   
   private void HandleSerialization()
   {
      SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs) 
                                      { 
                                          eventArgs.AddSerializedState(state);
                                      };
   }
   
   public Double Divisor
   { get { return state.Divisor; } }

   [Serializable] private struct BadDivisionExceptionState : ISafeSerializationData 
   {
      private Double badDivisor;
      
      public Double Divisor
      { get { return badDivisor; } 
        set { badDivisor = value; } }

      void ISafeSerializationData.CompleteDeserialization(object deserialized)
      { 
         var ex = deserialized as BadDivisionException;
         ex.HandleSerialization();
         ex.state = this; 
      }
   }
}
// The example displays the following output:
//       Serialized the exception...
//       Bad divisor from a new exception: 0
//       Reserialized the exception...
//       Bad divisor from a deserialized exception: 0
//       Reserialized the exception...
//       Bad divisor from a deserialized exception: 0
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
           
Module Example
   Public Sub Main()
      Dim serialized As Boolean = False
      Dim formatter As New BinaryFormatter()
      Dim values() As Double = { 3, 2, 1 }
      Dim divisor As Double = 0
      For Each value In values
         Try
            Dim ex As BadDivisionException = Nothing
            If divisor = 0 Then 
               If Not serialized Then
                  ' Instantiate the exception object.
                  ex = New BadDivisionException(0)
                  ' Serialize the exception object.
                  Dim fs As New FileStream("BadDivision1.dat", 
                                           FileMode.Create)
                  formatter.Serialize(fs, ex)
                  fs.Close()
                  Console.WriteLine("Serialized the exception...")
               Else
                  ' Deserialize the exception.
                  Dim fs As New FileStream("BadDivision1.dat",
                                           FileMode.Open)
                  ex = CType(formatter.Deserialize(fs), BadDivisionException)
                  ' Reserialize the exception.
                  fs.Position = 0
                  formatter.Serialize(fs, ex)
                  fs.Close()
                  Console.WriteLine("Reserialized the exception...")                                            
               End If   
              Throw ex 
            End If 
            Console.WriteLine("{0} / {1} = {1}", value, divisor, value/divisor)
         Catch e As BadDivisionException
            Console.WriteLine("Bad divisor from a {0} exception: {1}",
                              If(serialized, "deserialized", "new"), e.Divisor)             
            serialized = True
         End Try   
      Next
   End Sub
End Module

<Serializable> Public Class BadDivisionException : Inherits Exception
   ' Maintain an internal BadDivisionException state object.
   <NonSerialized> Private state As New BadDivisionExceptionState()

   Public Sub New(divisor As Double)
      state.Divisor = divisor
      HandleSerialization()      
   End Sub
   
   Private Sub HandleSerialization()
      AddHandler SerializeObjectState, 
                 Sub(exception As Object, eventArgs As SafeSerializationEventArgs)
                    eventArgs.AddSerializedState(state)
                 End Sub
   End Sub
   
   Public ReadOnly Property Divisor As Double
      Get
         Return state.Divisor
      End Get      
   End Property

   <Serializable> Private Structure BadDivisionExceptionState 
                                    Implements ISafeSerializationData
      private badDivisor As Double
      
      Public Property Divisor As Double
         Get
            Return badDivisor
         End Get
         Set
            badDivisor = value
         End Set
      End Property 

      Sub CompleteDeserialization(deserialized As Object) _
            Implements ISafeSerializationData.CompleteDeserialization
         Dim ex As BadDivisionException = TryCast(deserialized, BadDivisionException)
         ex.HandleSerialization()
         ex.state = Me 
      End Sub
   End Structure
End Class
' The example displays the following output:
'       Serialized the exception...
'       Bad divisor from a new exception: 0
'       Reserialized the exception...
'       Bad divisor from a deserialized exception: 0
'       Reserialized the exception...
'       Bad divisor from a deserialized exception: 0

BadDivisionException发生浮点除数为零时,将引发异常。The BadDivisionException exception is thrown when a floating-point division by zero occurs. 在第一个被零除的过程中,该BadDivisionException示例实例化一个对象,将其序列化,并引发异常。During the first division by zero, the example instantiates a BadDivisionException object, serializes it, and throws the exception. 如果后续除法运算发生,则此示例将反序列化以前序列化的对象,重新它,并引发异常。When subsequent divisions by zero occur, the example deserializes the previously serialized object, reserializes it, and throws the exception. 为了提供对象序列化、反序列化、reserialization 和反序列化,该SerializeObjectState示例BadDivisionExceptionISafeSerializationData.CompleteDeserialization类构造函数和实现中都添加了事件处理程序。To provide for object serialization, deserialization, reserialization, and deserialization, the example adds the SerializeObjectState event handler both in the BadDivisionException class constructor and in the ISafeSerializationData.CompleteDeserialization implementation.

注解

异常状态对象实现ISafeSerializationData接口。The exception state object implements the ISafeSerializationData interface.

当对SerializeObjectState事件进行订阅时,异常将反序列化并创建为空异常。When the SerializeObjectState event is subscribed to, the exception is deserialized and created as an empty exception. 异常的构造函数不会运行,并且异常状态也将进行反序列化。The exception's constructor is not run, and the exception state is also deserialized. 然后通知异常状态对象的回调方法,以便可以将反序列化的数据推送到空异常中。CompleteDeserializationThe CompleteDeserialization callback method of the exception state object is then notified so that it can push deserialized data into the empty exception.

SerializeObjectState事件使透明异常类型可以序列化和反序列化异常数据。The SerializeObjectState event enables transparent exception types to serialize and deserialize exception data. 透明代码可以在其运行的权限集边界内执行命令,但不能执行、调用、派生自或包含关键代码。Transparent code can execute commands within the bounds of the permission set it is operating within, but cannot execute, call, derive from, or contain critical code.

如果未对Exception 事件进行订阅,则使用构造函数照常进行SerializeObjectState反序列化。If the SerializeObjectState event is not subscribed to, deserialization occurs as usual using the Exception constructor.

通常情况下,会在SerializeObjectState异常的构造函数中添加事件的处理程序,以提供其序列化。Typically, a handler for the SerializeObjectState event is added in the exception's constructor to provide for its serialization. 但由于在SerializeObjectState事件处理程序执行时不执行构造函数,因此,序列化反序列化SerializationException异常会在您尝试反序列化异常时引发异常。But because the constructor is not executed when the SerializeObjectState event handler executes, serializing a deserialized exception can throw a SerializationException exception when you try to deserialize the exception. 若要避免此SerializeObjectState情况,还应ISafeSerializationData.CompleteDeserialization在方法中添加事件的处理程序。To avoid this, you should also add the handler for the SerializeObjectState event in the ISafeSerializationData.CompleteDeserialization method. 有关说明,请参阅示例部分。See the Examples section for an illustration.

继承者说明

如果此事件订阅并使用,则继承层次结构中后面的所有派生类型都必须实现相同的序列化机制。If this event is subscribed to and used, all derived types that follow in the inheritance hierarchy must implement the same serialization mechanism.

适用于