Exception.SerializeObjectState イベント

定義

注意事項

BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.

例外がシリアル化され、例外に関するシリアル化されたデータを含む例外状態オブジェクトが作成されたときに発生します。

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 定義します。 また、状態オブジェクトも含まれています。これは、インターフェイスを実装ISafeSerializationDataする名前BadDivisionExceptionStateの入れ子になった構造体です。

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 による浮動小数点除算が発生したときにスローされます。 0 による最初の除算の間に、この例ではオブジェクトを BadDivisionException インスタンス化し、シリアル化し、例外をスローします。 後続の 0 除算が発生すると、この例では、以前にシリアル化されたオブジェクトを逆シリアル化し、再シリアル化し、例外をスローします。 この例では、オブジェクトのシリアル化、逆シリアル化、再シリアル化、逆シリアル化を提供するために、クラス コンストラクターと実装の両方にBadDivisionExceptionイベント ハンドラーをISafeSerializationData.CompleteDeserialization追加SerializeObjectStateします。

注釈

例外状態オブジェクトは、インターフェイスを ISafeSerializationData 実装します。

イベントが SerializeObjectState サブスクライブされると、例外は逆シリアル化され、空の例外として作成されます。 例外のコンストラクターは実行されず、例外の状態も逆シリアル化されます。 CompleteDeserializationその後、逆シリアル化されたデータを空の例外にプッシュできるように、例外状態オブジェクトのコールバック メソッドに通知されます。

この SerializeObjectState イベントにより、透過的な例外の種類で例外データをシリアル化および逆シリアル化できます。 透過的なコードでは、実行中のアクセス許可セットの範囲内でコマンドを実行できますが、重要なコードを実行、呼び出し、派生、または含めることはできません。

イベントが SerializeObjectState サブスクライブされていない場合は、コンストラクターを使用して通常どおりに逆シリアル化が Exception 行われます。

通常、イベントの SerializeObjectState ハンドラーは、そのシリアル化を提供するために、例外のコンストラクターに追加されます。 ただし、イベント ハンドラーの実行時 SerializeObjectState にコンストラクターが実行されないため、逆シリアル化された例外をシリアル化すると、例外を逆シリアル化しようとすると例外がスロー SerializationException される可能性があります。 これを回避するには、メソッドにISafeSerializationData.CompleteDeserializationイベントのハンドラーをSerializeObjectState追加する必要もあります。 図については、「例」セクションを参照してください。

注意 (継承者)

このイベントをサブスクライブして使用する場合、継承階層に続く派生型はすべて、同じシリアル化メカニズムを実装する必要があります。

適用対象