Arbeitsspeicher läuft voll durch Sceenshots erstellen

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von King2k7.

    Arbeitsspeicher läuft voll durch Sceenshots erstellen

    Hallo,
    ich schreibe gerade ein Programm das regelmäßig ein Screenshot vom Desktop macht. Der Code läuft in einem Timer und wiederholt sich alle paar Minuten.
    Jetzt habe ich das Problem das mir der Arbeitsspeicher vollläuft, durch den Code mit dem die Screenshots gemacht werden.

    Weiß jemand wie ich dem Problem entgegen wirke bzw. Arbeitsspeicher wieder freigeben wenn der Code im Timer einmal durchgelaufen ist.

    C#-Quellcode

    1. void t1_Tick(object sender, EventArgs e)
    2. {
    3. // Capture the screen
    4. Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
    5. Graphics graphics = Graphics.FromImage(screenshot);
    6. graphics.CopyFromScreen(0, 0, 0, 0, screenshot.Size);
    7. //Farbcode auslesen
    8. Bitmap b = new Bitmap(screenshot);
    9. Color c = b.GetPixel(1333, 972);
    10. if (c.R.ToString() + c.G.ToString() + c.B.ToString() == "25079")
    11. {
    12. t1.Stop();
    13. Return();
    14. }
    15. }
    Edit: Habe jetzt etwas mit using herumprobiert. Damit ist die Arbeitsspeicherauslastung um einiges besser geworden. Aber nach wie vor steigt der verbrauch. Ich denke ich habe noch einen Fehler in der Verwendung.
    Gibt es verbesserungsvorschläge bezüglich des Codes um die Arbeitsspeicherauslastung zu minimieren?

    C-Quellcode

    1. void t1_Tick(object sender, EventArgs e)
    2. {
    3. System.Threading.Thread.Sleep(1500);
    4. // Capture the screen
    5. Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
    6. using (screenshot)
    7. {
    8. Graphics graphics = Graphics.FromImage(screenshot);
    9. using (graphics)
    10. {
    11. graphics.CopyFromScreen(0, 0, 0, 0, screenshot.Size);
    12. //Farbcode auslesen
    13. Bitmap b = new Bitmap(screenshot);
    14. Color c = b.GetPixel(1333, 972);
    15. if (c.R.ToString() + c.G.ToString() + c.B.ToString() == "25079")
    16. {
    17. t1.Stop();
    18. ReturnToMenu();
    19. }
    20. }
    21. }

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

    Unter der Annahme, dass sich dein PrimaryScreen nicht ändert, probier mal:

    VB.NET-Quellcode

    1. Private screenshot As Bitmap = New Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)
    2. Private graphics As Graphics = Graphics.FromImage(screenshot)
    3. Private Sub t1_Tick(sender As Object, e As EventArgs) Handles t1.Tick
    4. graphics.CopyFromScreen(0, 0, 0, 0, screenshot.Size)
    5. Dim c As Color = screenshot.GetPixel(1333, 972)
    6. If $"{c.R}{c.G}{c.B}" = "25079" Then
    7. t1.Stop()
    8. ReturnToMenu()
    9. EndIf
    10. End Sub

    c# Telerik-konvertiert

    C#-Quellcode

    1. private Bitmap screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
    2. private Graphics graphics = Graphics.FromImage(screenshot);
    3. private void t1_Tick(object sender, EventArgs e)
    4. {
    5. graphics.CopyFromScreen(0, 0, 0, 0, screenshot.Size);
    6. Color c = screenshot.GetPixel(1333, 972);
    7. if ($"{c.R}{c.G}{c.B}" == "25079")
    8. {
    9. t1.Stop();
    10. ReturnToMenu();
    11. }
    12. }

    Du machst immer wieder zwei neue BitMaps, die auch noch jeweils immer die gleichen sind am Ende.
    Stattdessen mach eine BitMap und mal immer wieder in diese eine rein.
    Using ist somit hier nicht notwendig, da die Disposables sowieso zur gesamten Laufzeit bereit stehen sollen.

    Da du ja scheinbar nur einen bestimmten Pixel prüfst, kannst du außerdem den Screenshot, den machst noch deutlich verkleinern. Aber gut das ist weniger relevant für den Arbeitsspeicher.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    was machst du denn mit den Bitmaps? Wenn du die irgendwie in eine list speicherst etc. ist klar das irgendwann der Arbeitsspeicher voll ist.
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    King2k7 schrieb:

    C#-Quellcode

    1. Bitmap b = new Bitmap(screenshot);
    Diese Instanz musst Du noch zerstören.
    Und

    C#-Quellcode

    1. if (c.R.ToString() + c.G.ToString() + c.B.ToString() == "25079")
    da machst Du Color.ToArgb() draus.
    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!