13 Stimmen

Warum versucht BinaryFormatter, ein Ereignis auf einer serialisierbaren Klasse zu serialisieren?

Ich habe eine einfache Klasse, die als Serializable markiert ist, und es geschieht, ein Ereignis zu haben. Ich habe versucht, das Ereignis-Mitglied als NonSerialized zu markieren, aber der Compiler beschwert sich. Wenn ich jedoch die Klasseninstanz serialisieren möchte, löst der BinaryFormatter eine Ausnahme aus, dass das Ereignis nicht serialisierbar ist. Heißt das, dass man Klassen, die Ereignisse haben, nicht serialisieren kann? Wenn ja, dann sollte der Compiler dies von vornherein sagen.

Stream file = File.Open("f", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();

object obj = null;
try
{
    obj = bf.Deserialize(file);
}
catch (System.Runtime.Serialization.SerializationException e)
{
    MessageBox.Show("De-Serialization failed : {0}", e.Message);
}
file.Close();

System.Collections.ArrayList nodeList = obj as System.Collections.ArrayList;

foreach (TreeNode node in nodeList)
{
    treeView.Nodes.Add(node);
}

Arbeitet nicht in der folgenden Klasse:

[Serializable()]
class Simple
{
    private int myInt;
    private string myString;
    public event SomeOtherEventDefinedElsewhere TheEvent;

}

27voto

Asad Punkte 20514

"Im Falle von Ereignissen müssen Sie auch den Feldattribut-Qualifikator hinzufügen, wenn Anwendung des Attributs NonSerialized hinzufügen, damit das Attribut angewendet wird den zugrundeliegenden Delegaten und nicht auf das Ereignis selbst" Erweiterte Serialisierung - MSDN


Präfix der NonSerializedAttribute mit Feld

[field:NonSerialized]
public event MyEventHandler MyEvent;

0voto

t0mm13b Punkte 33393

Es ist wichtig, daran zu denken, dass das Attribut [Field:NonSerialized] auf die Delegierten und nicht auf die Ereignisse angewandt wird (Groß- und Kleinschreibung wird beachtet), dann implementieren Sie ein ISerializable-Objekt und verwenden Sie Reflection, um die Klasse, die Sie serialisieren, nach dem Ereignishandler zu durchsuchen und die Ereignisse vor der Serialisierung abzubestellen. Wenn Sie dann die Deserialisierung durchführen, können Sie die Ereignisse bei Bedarf automatisch beim Deserialisieren verdrahten...

0voto

Anthony Punkte 594

Ich weiß, dies ist ein später Beitrag, aber hier ist eine aktuelle Antwort auf diese Frage. Erstellen Sie manuelle hinzufügen/entfernen "Getter/Setter" für Ihr Ereignis (der Compiler tut dies für Sie hinter den Kulissen, aber in diesem Fall müssen Sie dies explizit tun) dann markieren Sie Ihr Ereignis als NonSerialized. Ich habe keine Zeit, um den Code für Sie zu brechen, aber eine schnelle Suche zeigt jemand, der in das gleiche Problem lief:

http://sanity-free.org/113/csharp_binary_serialization_oddities.html

Diese Zeile sollte jedoch nicht verwendet werden: [MethodImpl(MethodImplOptions.Synchronized)]

Dies führt zu Problemen mit der Thread-Sicherheit, die in C# 4 behoben wurde; siehe :

http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

Sie müssen entweder Ihre eigene schlosslose Alternative rollen (mit CAS) oder online nach einer suchen; leider habe ich nicht die Zeit, da ich laufen muss, aber Sie verstehen die Idee.

Ich hoffe, das hilft!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X