2011-01-08 8 views
1

Ich bin jetzt von diesem Problem den ganzen Tag blockiert, lesen Sie Tausende von Google-Ergebnissen, aber nichts scheint mein Problem zu reflektieren oder sogar in die Nähe kommen ... ich hoffe, einer von Du hast einen Stoß in die richtige Richtung für mich.StackOverFlowException - aber oviously KEINE Rekursion/Endlosschleife

Ich schrieb eine Client-Server-Anwendung (also mehr wie 2 Anwendungen) - der Client sammelt Daten über sein System, sowie einen Screenshot, serialisiert all dies in einen XML-Stream (das Bild als ein Byte [] - Array]) und sendet dies in regelmäßigen Abständen an den Server. Der Server empfängt den Stream (via TCP), deserialisiert das XML in ein Informationsobjekt und zeigt die Informationen in einem Windows-Formular an. Dieser Prozess läuft ungefähr 20-25 Minuten bei einem Einreichungsintervall von 3 Sekunden stabil. Wenn man den Speicherverbrauch beobachtet, gibt es nichts Wesentliches zu sehen, auch nicht stabil. Aber nach diesen 20-25 Minuten löst der Server eine StackOverflowException an der Stelle aus, an der der tcp-Stream deserialisiert wird, besonders beim Setzen der Image-Eigenschaft aus dem byte [] - Array.

Ich suchte gründlich nach rekursiven oder endlosen Schleifen, und angesichts der Tatsache, dass es nach Tausenden von erfolgreichen Intervallen auftritt, konnte ich mir das kaum vorstellen.

public byte[] ImageBase 
    { 
     get 
     { 
      MemoryStream ms = new MemoryStream(); 
      _screen.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
      return ms.GetBuffer(); 
     } 
     set 
     { 
      if (_screen != null) _screen.Dispose(); //preventing well-known image memory leak 
      MemoryStream ms = new MemoryStream(value); 
      try 
      { 
       _screen = Image.FromStream(ms); //<< EXCEPTION THROWING HERE 
      } 
      catch (StackOverflowException ex) //thx to new CLR management this wont work anymore -.- 
      { 
       Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); 
      } 
      ms.Dispose(); 
      ms = null; 
     } 
    } 

Ich hoffe, dass mehr Code unnötig wäre, oder es könnte sehr komplex ...

Bitte helfen Sie, ich habe überhaupt keine Ahnung mehr

thx Chris

+0

Ich frage mich, was Sie in _screen = Image.FromStream (ms) tun, vielleicht setzen Sie ImageBase versehentlich? – Trap

+5

Ich mag SO Fragen zu SO. – Mehrdad

+0

sollten Sie die Verwendung von jedem MemoryStream wirklich in einen using() - Block schreiben, was es viel einfacher macht zu sehen, was richtig entsorgt wird! –

Antwort

3

Ich vermute, dass es nicht der Code ist, den Sie gepostet haben, sondern der Code, der aus dem TCP-Stream liest, der den Stack vergrößert. Die Tatsache, dass der Strohhalm während Image.FromStream passiert, ist wahrscheinlich irrelevant. Ich habe oft Leute gesehen, die einen Socket-Processing-Code schreiben, der selbstaufrufenden Code enthält (manchmal indirekt, wie A -> B -> A -> B). Sie sollten diesen Code einsehen und hier veröffentlichen, damit wir ihn betrachten können.

+0

Oh, und wenn Sie sich die Ausnahmedetails ansehen, sollten Sie sehen können, wie Ihr Call-Stack zum Zeitpunkt des Überlaufs aussieht. – Jacob

+0

hier ist es ... Listen() - Answer() - Listen() - Answer() wurden rekursiv -.- das gestern schon gefunden aber vergessen, dieses hier zu 'gelöst' zu setzen .. es tut mir leid, aber danke vielmals für deine Hilfe tho;) – tunefish

3

Vielleicht möchten Sie dies lesen. Loading an image from a stream without keeping the stream open

Es scheint möglich, dass Streams auf dem Stack oder einem anderen Objekt verwaltet werden, das den Stack schließlich durchbrennt.

Mein Vorschlag wäre, dann halten Sie einfach die byte[] und warten bis zum letzten möglichen Moment, um es zu dekodieren und zu zeichnen. dann entsorgen Sie das Bild sofort. Dein get/set würde dann gerade die byte[] setzen/bekommen. Sie würden dann eine benutzerdefinierte Zeichnungsroutine implementieren, die den aktuellen byte[] decodieren und zeichnen würde, um sicherzustellen, dass nicht mehr Ressourcen als nötig gespeichert werden.

aktualisiert

Wenn es eine Möglichkeit ist, dass Sie uns eine vollständige Stack-Trace erhalten können wir vielleicht weiter helfen können. Ich fange an zu denken, dass es nicht das Problem ist, wie ich es beschrieben habe. Ich habe ein Beispielprogramm erstellt, das genau wie in Ihrem Setter 10.000 Bilder erstellt hat, und es gab kein Problem. Wenn Sie ein Bild alle 3 Sekunden senden, sind das 30 Bilder pro Minute und 20 Minuten, also nur 600 Bilder.

Ich bin sehr interessiert an der Lösung dafür. Ich werde später darauf zurückkommen.

Es gibt jedoch ein paar Möglichkeiten, Remote.

  • Image.FromStream versucht ein ungültiges/beschädigtes Byte [] zu verarbeiten, und diese Methode verwendet Rekursion, um eine Bitmap zu decodieren. Sehr unwahrscheinlich.
  • Die Ausnahme wird nicht geworfen, wo Sie denken, dass es ist. Ein vollständiger Stack-Trace, wenn möglich, wäre sehr hilfreich. Wie Sie angegeben haben, können Sie keine StackOverflowException abfangen. Ich glaube, es gibt Bestimmungen dafür, wenn Sie es durch den Debugger jedoch ausführen.
  • +0

    Auch, und das ist nicht unbedingt eine Ursache für irgendetwas - der MemoryStream in der "Getter" sollte entsorgt werden, wie es IDisposable ist. –

    +0

    @Dave guten Ruf Ich habe diesen einen verpasst. Wenn er nur das Byte [] festhält, wird dies hoffentlich die meisten seiner Zuweisungsprobleme lindern. –

    1

    Ich bin mir nicht sicher, ob es relevant ist, aber die MSDN-Dokumentation für besagt, dass Sie müssen den Stream für die Lebensdauer des Image geöffnet lassen.

    +0

    nein, ich halte es NICHT offen;) es wirkt jetzt wie ein Charme;) – tunefish

    Verwandte Themen