Exception.SerializeObjectState Zdarzenie
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Przestroga
BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.
Występuje, gdy wyjątek jest serializowany w celu utworzenia obiektu stanu wyjątku zawierającego serializowane dane o wyjątku.
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)
Typ zdarzenia
- Atrybuty
Przykłady
W poniższym przykładzie zdefiniowano element BadDivisionException
, który obsługuje SerializeObjectState zdarzenie. Zawiera również obiekt stanu, który jest zagnieżdżonym strukturą o nazwie BadDivisionExceptionState
implementującą ISafeSerializationData interfejs.
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
Wyjątek BadDivisionException
jest zgłaszany, gdy wystąpi podział zmiennoprzecinkowa o zero. Podczas pierwszego dzielenia przez zero przykład tworzy wystąpienie BadDivisionException
obiektu, serializuje go i zgłasza wyjątek. Gdy kolejne podziały o zero występują, przykład deserializuje wcześniej serializowany obiekt, reerializuje go i zgłasza wyjątek. Aby zapewnić serializacji obiektów, deserializacji, reserializacji i deserializacji, przykład dodaje SerializeObjectState procedurę obsługi zdarzeń zarówno w BadDivisionException
konstruktorze klasy, jak i w implementacji ISafeSerializationData.CompleteDeserialization .
Uwagi
Obiekt stanu wyjątku ISafeSerializationData implementuje interfejs.
SerializeObjectState Po zasubskrybowaniu zdarzenia wyjątek jest deserializowany i tworzony jako pusty wyjątek. Konstruktor wyjątku nie jest uruchamiany, a stan wyjątku jest również deserializowany. Metoda CompleteDeserialization wywołania zwrotnego obiektu stanu wyjątku jest następnie powiadamiana, aby mogła wypchnąć deserializowane dane do pustego wyjątku.
Zdarzenie SerializeObjectState umożliwia przezroczyste typy wyjątków w celu serializacji i deserializacji danych wyjątków. Przezroczysty kod może wykonywać polecenia w granicach zestawu uprawnień, w ramach którego działa, ale nie może wykonywać, wywoływać, pochodzić z lub zawierać kod krytyczny.
SerializeObjectState Jeśli zdarzenie nie jest subskrybowane, deserializacja występuje jak zwykle przy użyciu konstruktoraException.
Zazwyczaj procedura obsługi zdarzenia SerializeObjectState jest dodawana w konstruktorze wyjątku w celu zapewnienia jego serializacji. Jednak ponieważ konstruktor nie jest wykonywany podczas SerializeObjectState wykonywania procedury obsługi zdarzeń, serializowanie deserializacji wyjątku może zgłosić SerializationException wyjątek podczas próby deserializacji wyjątku. Aby tego uniknąć, należy również dodać procedurę obsługi dla SerializeObjectState zdarzenia w metodzie ISafeSerializationData.CompleteDeserialization . Zobacz sekcję Przykłady, aby zapoznać się z ilustracją.
Uwagi dotyczące dziedziczenia
Jeśli to zdarzenie jest subskrybowane i używane, wszystkie typy pochodne, które następują w hierarchii dziedziczenia, muszą zaimplementować ten sam mechanizm serializacji.