Exception.SerializeObjectState 이벤트

정의

주의

BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId="SYSLIB0011", UrlFormat="https://aka.ms/dotnet-warnings/{0}

예외에 대한 serialize된 데이터가 들어 있는 예외 상태 개체가 만들어지도록 예외가 serialize될 때 발생합니다.

protected:
 event EventHandler<System::Runtime::Serialization::SafeSerializationEventArgs ^> ^ SerializeObjectState;
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs>? SerializeObjectState;
[System.Obsolete("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId="SYSLIB0011", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs>? SerializeObjectState;
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> SerializeObjectState;
member this.SerializeObjectState : EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> 
[<System.Obsolete("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.", DiagnosticId="SYSLIB0011", UrlFormat="https://aka.ms/dotnet-warnings/{0}")>]
member this.SerializeObjectState : EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> 
Protected Custom Event SerializeObjectState As EventHandler(Of SafeSerializationEventArgs) 

이벤트 유형

EventHandler<SafeSerializationEventArgs>
특성

예제

다음 예제에서는 이벤트를 처리 하는 정의 BadDivisionException 합니다 SerializeObjectState . 또한 인터페이스를 구현하는 중 BadDivisionExceptionState 첩된 구조체인 상태 개체도 포함됩니다 ISafeSerializationData .

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 부동 소수점 나누기(0)가 발생하면 예외가 throw됩니다. 첫 번째 나누기 동안 0으로 분할하는 동안 예제에서는 개체를 BadDivisionException 인스턴스화하고 직렬화하고 예외를 throw합니다. 후속 나누기가 0으로 발생하면 예제는 이전에 직렬화된 개체를 역직렬화하고, 다시 역직렬화하고, 예외를 throw합니다. 개체 serialization, deserialization, reserialization 및 deserialization을 제공하기 위해 예제에서는 클래스 생성자와 구현 모두에서 BadDivisionException 이벤트 처리기를 ISafeSerializationData.CompleteDeserialization 추가합니다SerializeObjectState.

설명

예외 상태 개체는 인터페이스를 ISafeSerializationData 구현합니다.

SerializeObjectState 이벤트를 구독하면 예외가 역직렬화되고 빈 예외로 생성됩니다. 예외의 생성자가 실행되지 않으며 예외 상태도 역직렬화됩니다. CompleteDeserialization 그런 다음, 역직렬화된 데이터를 빈 예외로 푸시할 수 있도록 예외 상태 개체의 콜백 메서드에 알림이 표시됩니다.

SerializeObjectState 이벤트를 사용하면 투명한 예외 형식이 예외 데이터를 직렬화하고 역직렬화할 수 있습니다. 투명한 코드는 작동 중인 권한 집합의 범위 내에서 명령을 실행할 수 있지만 중요한 코드를 실행, 호출, 파생 또는 포함할 수는 없습니다.

SerializeObjectState 이벤트를 구독하지 않으면 생성자를 사용하여 평소와 같이 역직렬화가 Exception 발생합니다.

일반적으로 이벤트에 대한 SerializeObjectState 처리기는 해당 serialization을 제공하기 위해 예외의 생성자에 추가됩니다. 그러나 이벤트 처리기가 실행될 때 SerializeObjectState 생성자가 실행되지 않으므로 역직렬화된 예외를 직렬화하면 예외를 역직렬화하려고 할 때 예외가 throw SerializationException 될 수 있습니다. 이 문제를 방지하려면 메서드에서 이벤트에 ISafeSerializationData.CompleteDeserialization 대한 SerializeObjectState 처리기도 추가해야 합니다. 일러스트레이션은 예제 섹션을 참조하세요.

상속자 참고

이 이벤트를 구독하고 사용하는 경우 상속 계층 구조에서 뒤에 오는 모든 파생 형식은 동일한 serialization 메커니즘을 구현해야 합니다.

적용 대상