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)
Тип события
- Атрибуты
Примеры
В следующем примере определяется 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
возникает, когда происходит деление с плавающей запятой на ноль. Во время первого деления на ноль в примере создается экземпляр BadDivisionException
объекта, сериализуется и создается исключение. При последующих делениях на ноль выполняется десериализация ранее сериализованного объекта, его повторное инициализация и исключение. Для обеспечения сериализации объектов, десериализации, повторной и десериализации в примере добавляется SerializeObjectState обработчик событий как в BadDivisionException
конструктор класса, так и в ISafeSerializationData.CompleteDeserialization реализации.
Комментарии
Объект состояния исключения реализует ISafeSerializationData интерфейс.
SerializeObjectState Когда событие подписывается, исключение десериализуется и создается как пустое исключение. Конструктор исключения не выполняется, а состояние исключения также десериализуется. Затем CompleteDeserialization метод обратного вызова объекта состояния исключения уведомляется, чтобы он смог отправить десериализованные данные в пустое исключение.
Это SerializeObjectState событие позволяет прозрачным типам исключений сериализовать и десериализовать данные исключений. Прозрачный код может выполнять команды в пределах набора разрешений, в котором он работает, но не может выполнять, вызывать, наследовать или содержать критический код.
SerializeObjectState Если событие не подписано, десериализация выполняется обычным образом с помощью конструктораException.
Как правило, обработчик события SerializeObjectState добавляется в конструктор исключения для обеспечения его сериализации. Но поскольку конструктор не выполняется при SerializeObjectState выполнении обработчика событий, сериализация десериализованного исключения может вызвать SerializationException исключение при попытке десериализовать исключение. Чтобы избежать этого, необходимо также добавить обработчик события SerializeObjectState в ISafeSerializationData.CompleteDeserialization метод. См. раздел "Примеры" для иллюстрации.
Примечания для тех, кто наследует этот метод
Если это событие подписывается и используется, все производные типы, которые следуют в иерархии наследования, должны реализовать один и тот же механизм сериализации.