GDI Zeichenfehler anzeigen
- VB.NET
- .NET (FX) 4.0
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 47 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.
-
-
GC.Collect
soll man garnicht aufrufen.
Das bringt nur den Collecting-Algo durcheinander - besser wird dadurch bestimmt nichts.
(also ich habs nicht geprüft, ich gebe hier nur wieder, wass ich an verschiedenen Stellen im Inet aufgeschnappt hab, und was mir plausibel erschien - aber die Stellen kann ich jetzt auch nicht mehr angeben) -
Gather schrieb:
Sie werden doch direkt danach disposed?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! -
Dispose zerstört nur die zugrundeliegenden GDI objekte, welche mittels WinAPI erzeugt werden, nicht jedoch die .Net Wrapper Objekte, die sollten irgendwann vom GC aufgeräumt werden, die Frage ist allerdings warum das nicht passiert. Hast du die Diagnosesitzung mal bis zum Ende durchlaufen lassen? Vlt. auch ein paar Snapshots machen, sodass man eine Steigerung von bestimmten Objekten sieht. Denn eigt. sollten die LinearGradientBrush spätestens aufgeräumt werden, wenn der Speicher ausgeht.
Es sieht aber auch so aus, als könnte man die Brushes poolen, wäre vlt. auch eine Idee, falls die tatsächlich schuld sind.
Edit: GC.Collect sollte man tatsächlich selten verwenden, heißt aber nicht, dass man es gar nicht verwenden soll, manchmal ist der Programmierer schlauer als der GC und weiß wann aufgeräumt werden darf und wann nicht. Nur sollte das bei Business Anwendungen so gut wie nie der Fall sein. Wenn es um Grafikrendering geht aber schon eher.
Ich wollte auch mal ne total überflüssige Signatur:
---Leer--- -
jvbsl schrieb:
Denn eigt. sollten die LinearGradientBrush spätestens aufgeräumt werden, wenn der Speicher ausgeht.
Edit://
Bezüglich der DiagnoseSitzung und den Snapshots. Wie genau funktioniert das? Ich habe bisher noch nie dieses Feature verwendet
Edit:// Problem ist auch, dass man bei Drawing2D.LinearGradientBrush die Punkte, nach dem Erstellen, nicht mehr verändern kann.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Gather“ ()
-
@Gather Wie schnell hintereinander wird denn diese Prozedur aufgerufen?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! -
@RodFromGermany: Grundsätzlich ca alle 50ms. ALLERDINGS tut dies nicht zur Sache. Denn in Tests hat sich gezeigt, dass selbst wenn die Prozedur nur jede halbe oder gar ganze Sekunde aufgerufen wird,
es früher oder später auch zu dem Fehler "Nicht genügend Arbeitsspeicher vorhanden." kommt. Mit 50ms passiert dies ganz einfach nur schneller... -
Tja, dann fällt mir fürs Pooling nur ein:
referencesource.microsoft.com/…ed/LinearGradientBrush.cs
Entweder das komplette Teil schnappen und neu bauen, oder eben
mittels Reflection "void SetNativeBrushInternal(IntPtr brush)" auf zu rufen um die Objekte zu switchen und eben nur die GDI handles erzeugen/zu löschen indem du die Konstruktoren extra implementierst^^
Aber kommt mir alles unschön vor, hört sich irgendwie nach einem Bug an das ganzeIch wollte auch mal ne total überflüssige Signatur:
---Leer--- -
Es gibt also kurz und knapp keine möglichkeit die punkte in einem lineargradientbrush zu verändern?
Das Einzige was ich jetzt auf die schnelle gesehen hätte wäre die .Blend Property, aber ich kann mir nicht vorstellen wie ich zwei Punkte in Single konvertieren könnte. -
Gather schrieb:
die punkte in einem lineargradientbrush zu verändernFalls 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! -
-
Gather schrieb:
Das ist korrekt. Passiert auch (denke ich), wenn man das Ganze ebenfalls durch ein TryCatch laufen lässt, flackert es lediglich eine Millisekunde wenn der Speicher voll ist. Das Kreuz kann damit also vermieden werden, allerdings ist das mit dem TryCatch nicht der schönste Weg.
D.h.: Der Fehler tritt nachwievor auf, kann aber übergangen werden ohne Folgefehler (flackert dann nur bischen).
richtig?
Gather schrieb:
Grundsätzlich ca alle 50ms. ALLERDINGS tut dies nicht zur Sache...
Mich jdfs. würde jetzt brennend interessieren, wie du die Zeichenroutine aufrufst. -
Ich glaub nicht, das dass n Bug ist. Referencesource sieht ja auch erstmal i.O. aus. Aufgeräumt wird in der Basisklasse Brush, also müsste es bei allen Brushes sein. Ich weiß auch nicht wie genau es intrrn in GDI+ läuft, die C++ Objekte muss man z.B. nicht aufräumen, wird alles normal im Destruktor gemacht. Kannst du denn kein Testprojekt hochladen? Würde mich nämlich auch interessieren. Hast du denn die LinearGradientBrush einfach mal auskommentiert und erneut getestet? Btw bist du dir sicher, dass man die Punkte nicht nicht ändern kann? Glaube das ging über die Blend. Speichermäßig alle 50ms eine neue Brush erzeugen ist ja erstmal egal, aber für die Performance natürlich Katastrophe.
-
ErfinderDesRades schrieb:
Mich jdfs. würde jetzt brennend interessieren, wie du die Zeichenroutine aufrufst. -
ErfinderDesRades schrieb:
richtig?
Das ist korrekt.
Zusätzlich sieht die Zeichenmethode 1zu1 aus wie oben angeben. Aufgerufen wird es simpel mit Invalidate(), via Timer.
Und ja das Problem Tritt auf wenn der Timer auf 50ms ist, sowie wenn er auf 1000 ist.
Edit:// Demoprojekt folgt.Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Gather“ ()
-
Hey, ich habe festgestellt das die OutOfMemoryException dann auftritt wenn
p.Location
die gleichen koordinaten wiepossiblePoint.Location
hat. So läuft es anständig durch.
VB.NET-Quellcode
- Public Sub DrawGalaxy(g As Graphics, points As BoundPoint(), _
- Optional connectionDistance As Integer = 50, _
- Optional lineAlpha As Integer = 50, _
- Optional useOverlayColor As Boolean = False)
- g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
- If points.Length >= 1 Then
- ' Try
- Dim b As New SolidBrush(_OverlayColor)
- For Each p In points
- For Each possiblePoint In points
- If possiblePoint IsNot p Then
- Dim d As Double = MeasurePointDistance(p.Location, possiblePoint.Location)
- If d < connectionDistance Then
- If p.Color.A < lineAlpha Then lineAlpha = p.Color.A
- Dim lgb As LinearGradientBrush = Nothing
- If p.Location <> possiblePoint.Location Then
- lgb = New LinearGradientBrush(p.Location, possiblePoint.Location, Color.FromArgb(lineAlpha, p.Color), Color.FromArgb(lineAlpha, possiblePoint.Color))
- Using Pen As New Pen(lgb)
- g.DrawLine(Pen, p.Location, possiblePoint.Location)
- End Using
- End If
- If lgb IsNot Nothing Then
- lgb.Dispose()
- End If
- End If
- End If
- Next
- b.Color = If(useOverlayColor, _OverlayColor, p.Color)
- g.FillEllipse(b, New Rectangle(p.Location.X - CInt(p.Width / 2), p.Location.Y - CInt(p.Width / 2), p.Width, p.Width))
- Next
- b.Dispose()
- ' Catch ex As Exception
- ' Im Normalfall nur ausgelöst wenn Arbeitsspeicher voll.
- ' End Try
- End If
- End Sub
Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
„Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
Benjamin Franklin -
@NoIde
Wow. Faszinierend, es funktioniert.!
Wobei ich zugeben muss, dass mir nicht klar ist wieso...
Funktioniert sogar mit mehreren hundert Punkten, sowie einem Intervall von 30ms.
Edit://
Oh verstehe. Danke für deine Hilfe!
-
-
Gerne doch. Tipp für das nächste mal, in dem ich erkläre wie ich das fand. Ich habe erstmal den Try/Catch rauskommentiert, in der Zeile in der du den LinearGradientBrush erstellt hast, kam es zu der Exception, im wieder rein kommentierten Try/Catch habe ich mir dann einfach mal die Variablen im Catch angeschaut, welche du zur erzeugung nutzt, so konnte ich die identischen Koordinaten als Ursache erkennen.
Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
„Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
Benjamin FranklinDieser Beitrag wurde bereits 3 mal editiert, zuletzt von „NoIde“ ()
-
-
Benutzer online 2
2 Besucher
-
Tags
-
Ähnliche Themen
-
9 Benutzer haben hier geschrieben
- Gather (15)
- RodFromGermany (9)
- ErfinderDesRades (8)
- NoIde (4)
- jvbsl (4)
- Gonger96 (4)
- zorroot (2)
- Fakiz (1)
- Blackn0va (1)