Probleme mit dem Serialisieren in XML

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von MidiProgger76.

    Probleme mit dem Serialisieren in XML

    Hallo,

    ich habe hier ein Problem, das ich nur sehr vage beschreiben kann. Ich habe Windows 10 installiert und meine Software lief normal. Aber irgendwann blieb meine Software immer bei dieser Zeile stehen.

    VB.NET-Quellcode

    1. Dim xSer As XmlSerializer = New XmlSerializer(GetType(Harmo.HarmonicaSetup))


    Das Kuriose ist, dass das Problem im Kompatibilitäsmodus zu Windows 7 nicht auftritt.

    Hat jemand irgendeine Idee, was eine Rolle spielen könnte?

    Das Programm ist übrigens 32 Bit (x86) - VB 2013.

    Über Tipps würde ich mich freuen.

    Tobias
    If she IsNot here then sunshine = false

    MidiProgger76 schrieb:

    bei dieser Zeile
    Poste bitte mal ein testbares Snippet.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hm, das Problem ist, dass das Programm sehr umfangreich ist. Ich weiß jetzt nicht, wie ich ein Snippet hinbekomme, wo sich der Fehler reproduzieren lässt. Ich habe ein anderes Projekt erstellt, aber da hatte ich den Fehler nicht.

    Ich will da folgende Klasse aus einer Datei deserialisieren.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. <Serializable()> Public Class HarmonicaSetup
    2. Implements ICloneable
    3. Public Function Clone() As Object Implements System.ICloneable.Clone
    4. Dim msBuf As New MemoryStream
    5. Dim bf As New BinaryFormatter
    6. bf.Serialize(msBuf, Me)
    7. msBuf.Position = 0
    8. Return bf.Deserialize(msBuf)
    9. End Function
    10. Public Sub New()
    11. End Sub
    12. Public JoyControl As Boolean = True
    13. Public MouseDualNotes As Boolean = False
    14. Public JoyDualNotes As Boolean = False
    15. Public Min As Integer = 0
    16. Public Max As Integer = 65535
    17. Public Joy As Integer = 0 'for storing the joystick
    18. Public Axis As Integer = 0 'for storing the axis
    19. Public TriggerJoy1 As Integer = 0 ' for storing the triggering joystick
    20. Public TriggerJoy2 As Integer = 0 'for button2
    21. Public TriggerAxis As Integer = 2 'for storing the triggering axis
    22. Public TriggerThresholdLow As Integer
    23. Public TriggerThresholdHigh As Integer
    24. Public Button1 As Integer = 0
    25. Public Button2 As Integer = 1
    26. Public TriggerType1 As InpType = InpType.JoyAxis 'Integer enum
    27. Public TriggerType2 As InpType = InpType.JoyButton 'for button2 (only mouse/joy buttons, no axis)
    28. Public Scale As Integer 'for storing the assigned scale
    29. Public CustomNoteNames As Boolean = False
    30. Public Locked As Boolean = False
    31. Public Bus As Integer = 0
    32. <NonSerialized()> <XmlIgnore()> Public iValue1 As Integer = 0
    33. End Class



    Aber bevor irgendwas passieren kann, geht es nicht mehr weiter. Die Deklaration des XML Serialisers hält das Programm schon an.
    If she IsNot here then sunshine = false

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MidiProgger76“ ()

    MidiProgger76 schrieb:

    XML Serialiser
    Folgendes funktioniert bei mir:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Xml.Serialization
    3. Public Class Form1
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim harm As New HarmonicaSetup()
    6. harm.Min = 42
    7. harm.Max = 333
    8. 'Serialize object to a text file.
    9. Using sw As New StreamWriter("C:\Temp\Harmonica.xml")
    10. Dim x As New XmlSerializer(harm.GetType())
    11. x.Serialize(sw, harm)
    12. End Using
    13. End Sub
    14. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    15. Dim harm As New HarmonicaSetup()
    16. 'Deserialize text file to a new object.
    17. Using sr As New StreamReader("C:\Temp\Harmonica.xml")
    18. Dim x As New XmlSerializer(harm.GetType())
    19. harm = CType(x.Deserialize(sr), HarmonicaSetup)
    20. End Using
    21. MessageBox.Show(harm.Min.ToString)
    22. End Sub
    23. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo, ich bin immer noch nicht weitergekommen. In meiner Software habe ich nochmal was versucht in der Art:

    VB.NET-Quellcode

    1. <Serializable()> Public Class TestClass
    2. Public VarA As Integer = 9
    3. Public VarB As Integer = 7
    4. Public strX As String = "Test"
    5. End Class
    6. Dim tc As New TestClass


    Im Load Ereignis bzw. in einer Sub, die von da aufgerufen wird, mache ich folgendes:

    VB.NET-Quellcode

    1. Dim xSer As XmlSerializer = New XmlSerializer(tc.GetType)


    Und das Programm bleibt stehen! Es gibt keine Fehlermeldung, es passiert einfach nichts. Ich bin am verzweifeln. Das Seltsame ist nach wie vor, dass das Programm im Windows 7 Kompatibilitätsmodus einwandfrei läuft. Habe einfach keine Idee, wo ich ansetzen soll, das Problem zu lösen. Es kann doch nicht sein, dass ich auf XML verzichten muss. Das muss doch funktionieren.

    Gruß

    Tobias
    If she IsNot here then sunshine = false

    MidiProgger76 schrieb:

    Und das Programm bleibt stehen!
    In welcher Zeile?
    Wie ist Dein Output-Pfad?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hier. Nach dieser Zeile passiert nichts mehr.

    VB.NET-Quellcode

    1. Dim xSer As XmlSerializer = New XmlSerializer(tc.GetType)


    Was meinst du mit Output Pfad? Ich sehe gerade, dass ich hier Deserialisieren meine ;) Es wird eine Datei gelesen, die in einem Ordner unter Appdata liegt.

    ThuCommix schrieb:

    Du
    musst noch Deserialize bzw Serialize aufrufen?


    Soweit komme ich leider nicht. Die nächste Zeile wäre das:

    VB.NET-Quellcode

    1. GlobalSet = DirectCast(xSer.Deserialize(sr), GlobalSettings)



    If she IsNot here then sunshine = false

    MidiProgger76 schrieb:

    Die nächste Zeile wäre das:
    Poste bitte mal den kompletten Code.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ist schwierig mit dem kompletten Code. Es wird so einiges abgearbeitet im Load Ereignis und das würde den Rahmen sprengen, da ich jede Routine komplett posten müsste. Ich muss mal gucken, was ich da zeigen könnte.

    Davon abgesehen ist das Problem seltsam beschaffen, weil schon die Deklaration nicht klappt. Wie kann das Programm einfach stoppen, wenn diese Zeile kommt? Auch wenn ich das als erstes im Load Ereignis mache!

    VB.NET-Quellcode

    1. Dim xSer As New XmlSerializer(GetType(GlobalSettings), "GlobalSettings")


    Bei Globalsettings handelt es sich um folgende Klasse:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. <Serializable()> Public Class GlobalSettings 'Global program setting (GlobalSet variable)
    2. Implements ICloneable
    3. Public GlobalJoystick As Boolean = True
    4. Public JBMouseSwitchTime As Integer = 350
    5. Public PianoShowSipSel As Boolean = True
    6. Public PianoShowPuffSel As Boolean = True
    7. Public HarmoShowTriggered As Boolean = True 'Show current played note
    8. Public LockWinPos As Boolean = True
    9. Public LockWinSize As Boolean = True
    10. Public LockWinOnTop As Boolean = False
    11. Public LockMIDIPort As Boolean = False
    12. Public HarFixHeightMode As Boolean = False
    13. Public HarFixHeight As Integer = 100
    14. Public TimerInterval As Integer = 5
    15. Public NoteDelay As Integer = 0 'in ms. For avoiding hanging notes
    16. Public KSHoldTime As Integer = 8 'hold time for keyswitch-notes
    17. Public PianoMidiCh As Integer = 0 'Midi Channel for Mouse Piano (0-15)
    18. Public Sub New()
    19. End Sub
    20. Public Function Clone() As Object Implements System.ICloneable.Clone
    21. Dim msBuf As New MemoryStream
    22. Dim bf As New BinaryFormatter
    23. bf.Serialize(msBuf, Me)
    24. msBuf.Position = 0
    25. Return bf.Deserialize(msBuf)
    26. End Function
    27. End Class


    Gibt es keine Einstellungen, die man vornehmen kann, um die Situation zu ändern? Irgendwas im Zusammenhang mit der Serialisierung.

    Grüße

    Tobias
    If she IsNot here then sunshine = false

    MidiProgger76 schrieb:

    Es wird so einiges abgearbeitet im Load Ereignis...
    Ja, das ist schlecht, weil im Load-Event kann man nicht vernünftig debuggen.
    Nimm den Code aus dem Load-Event heraus, und verfrachte ihn ins Shown-Event, dort kriegt man sinnvolle Fehlermeldungen, statt dass die Code-Ausführung einfach aufhört.

    RodFromGermany schrieb:

    Poste bitte mal den kompletten Code
    der Serialisierung selbst, nicht aber der serialisierten Klasse.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So, ich habe jetzt ein neues Projekt erstellt, das das gleiche Verhalten zeigt. Hier ist es:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. 'Imports System.Threading
    3. Imports System
    4. Imports System.Runtime.Serialization.Formatters.Binary
    5. Imports System.Runtime.Serialization
    6. Imports System.Xml.Serialization
    7. Public Class Form1
    8. <Serializable()> Public Class GlobalSettings 'Global program setting (GlobalSet variable)
    9. Implements ICloneable
    10. Public GlobalJoystick As Boolean = True
    11. Public JBMouseSwitchTime As Integer = 350
    12. Public PianoShowSipSel As Boolean = True
    13. Public PianoShowPuffSel As Boolean = True
    14. Public HarmoShowTriggered As Boolean = True 'Show current played note
    15. Public LockWinPos As Boolean = True
    16. Public LockWinSize As Boolean = True
    17. Public LockWinOnTop As Boolean = False
    18. Public LockMIDIPort As Boolean = False
    19. Public HarFixHeightMode As Boolean = False
    20. Public HarFixHeight As Integer = 100
    21. Public TimerInterval As Integer = 5
    22. Public NoteDelay As Integer = 0 'in ms. For avoiding hanging notes
    23. Public KSHoldTime As Integer = 8 'hold time for keyswitch-notes
    24. Public PianoMidiCh As Integer = 0 'Midi Channel for Mouse Piano (0-15)
    25. Public Sub New()
    26. End Sub
    27. Public Function Clone() As Object Implements System.ICloneable.Clone
    28. Dim msBuf As New MemoryStream
    29. Dim bf As New BinaryFormatter
    30. bf.Serialize(msBuf, Me)
    31. msBuf.Position = 0
    32. Return bf.Deserialize(msBuf)
    33. End Function
    34. End Class
    35. Dim GlobalSet As New GlobalSettings
    36. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    37. Dim xSer As XmlSerializer
    38. xSer = New XmlSerializer(GlobalSet.GetType, "GlobalSettings")
    39. MsgBox("Die letzte Zeile wurde ausgeführt.")
    40. End Sub
    41. End Class


    Wenn alles funktioniert, sollte die Msgbox auftauchen. Im Normalfall erscheint sie nicht. Im Kompatibilitätsmodus zu Windows 7 schon. Ich habe Windows 10 Pro 64 Bit. Verwendet habe ich VS2013. Das .net Framework 3.5. Es ist eine 32 Bit Anwendung.

    Es ist übrigens egal, wo ich die Zeile ausführe. Ich habe es auch mit einem Button versucht. Auch da bleibt alles stehen und ich bekomme keine Fehlermeldung.
    If she IsNot here then sunshine = false

    MidiProgger76 schrieb:

    Wenn alles funktioniert, sollte die Msgbox auftauchen
    Funktioniert sofort.

    Wenn wir das Projekt aufräumen und alles in separate (Shared) Klassen packen, kommt dies raus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public Shared GlobalSet As GlobalSettings
    3. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
    4. SerializationGlobalSettings.Load()
    5. SerializationGlobalSettings.Save()
    6. MessageBox.Show("Die letzte Zeile wurde ausgeführt.")
    7. End Sub
    8. End Class

    VB.NET-Quellcode

    1. Imports System.IO
    2. Imports System.Runtime.Serialization.Formatters.Binary
    3. <Serializable()> Public Class GlobalSettings 'Global program setting (GlobalSet variable)
    4. Implements ICloneable
    5. Public GlobalJoystick As Boolean = True
    6. Public JBMouseSwitchTime As Integer = 350
    7. Public PianoShowSipSel As Boolean = True
    8. Public PianoShowPuffSel As Boolean = True
    9. Public HarmoShowTriggered As Boolean = True 'Show current played note
    10. Public LockWinPos As Boolean = True
    11. Public LockWinSize As Boolean = True
    12. Public LockWinOnTop As Boolean = False
    13. Public LockMIDIPort As Boolean = False
    14. Public HarFixHeightMode As Boolean = False
    15. Public HarFixHeight As Integer = 100
    16. Public TimerInterval As Integer = 5
    17. Public NoteDelay As Integer = 0 'in ms. For avoiding hanging notes
    18. Public KSHoldTime As Integer = 8 'hold time for keyswitch-notes
    19. Public PianoMidiCh As Integer = 0 'Midi Channel for Mouse Piano (0-15)
    20. Public Function Clone() As Object Implements System.ICloneable.Clone
    21. Using msBuf As New MemoryStream
    22. Dim bf As New BinaryFormatter
    23. bf.Serialize(msBuf, Me)
    24. msBuf.Position = 0
    25. Return bf.Deserialize(msBuf)
    26. End Using
    27. End Function
    28. End Class

    VB.NET-Quellcode

    1. Imports System.Xml.Serialization
    2. Imports System.Text
    3. Imports System.IO
    4. Public Class SerializationGlobalSettings
    5. Private Shared MyPath As String
    6. Shared Sub New()
    7. SerializationGlobalSettings.MyPath = "c:\Temp\MySettings.xml"
    8. End Sub
    9. Public Shared Sub Save()
    10. ' Serialize object to a XML file.
    11. Using sw As New StreamWriter(SerializationGlobalSettings.MyPath, False, Encoding.Default)
    12. Dim x As New XmlSerializer(Form1.GlobalSet.GetType())
    13. x.Serialize(sw, Form1.GlobalSet)
    14. End Using
    15. End Sub
    16. Public Shared Sub Load()
    17. Form1.GlobalSet = New GlobalSettings()
    18. Try
    19. Dim fi As New FileInfo(SerializationGlobalSettings.MyPath)
    20. If fi.Exists Then
    21. ' Deserialize XML file to a new object.
    22. Using sr As New StreamReader(SerializationGlobalSettings.MyPath, Encoding.Default)
    23. Dim x As New XmlSerializer(Form1.GlobalSet.GetType())
    24. Form1.GlobalSet = DirectCast(x.Deserialize(sr), GlobalSettings)
    25. End Using
    26. End If
    27. ' nix tun, die Settings-Instanz ist nicht valid
    28. Catch
    29. End Try
    30. End Sub
    31. End Class
    mit diesem Output:
    MySettings.xml
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Ich habe jetzt festgestellt, dass das Problem nur bei 32 Bit besteht. Stelle ich es auf 64 Bit um, läuft es.

    Ich hätte nichts dagegen, mein Programm auf 64 Bit umzustellen, aber da müsste viel umgebaut werden. Vieles ist da auf 32 Bit ausgelegt und ich weiß nicht, wie ich das umbauen kann.
    If she IsNot here then sunshine = false
    Die Joystick Routinen, die auf einer älteren 32-Bit DirectX Version basieren. Da werden auch die Assemblies mscorlib.dll und PresentationCore genannt.

    Das Hauptfenster wird nicht angezeigt, weil Variablen oder Steuerelemente nicht deklariert oder zugeordnet sind. Da gibt es entsprechende Meldungen.

    Das ist mir (noch) zu hoch ;)
    If she IsNot here then sunshine = false