myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: Windows-Forms » [erledigt] DrawImage blockiert GUI Thread
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[erledigt] DrawImage blockiert GUI Thread

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
harrylask harrylask ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.07.2005
Beiträge: 59
Herkunft: Salzburg


harrylask ist offline

[erledigt] DrawImage blockiert GUI Thread

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Leute,
ich erstelle in einer asynchronen Methode die zyklisch aufgerufen wird ein Bitmap welches ich am Ende je nach Fenstergrösse skaliere, funktioniert prinzipiell einwandfrei. Der Haken ist das mir die Anweisung Graphics.DrawImage() für einen Bruchteil den GUI Thread blockiert.

C#-Code:
    private void timer1_Tick(object sender, EventArgs e)
    {
      new MethodInvoker(this.Test).BeginInvoke(null, null);
    }

    private void Test()
    {
      Bitmap Source = new Bitmap(4380, 1650);
      Bitmap Destination = new Bitmap((int)(Source.Width * 0.26F), (int)(Source.Height * 0.26F));

      using (Graphics g1 = Graphics.FromImage(Source))
      {
        g1.Clear(Color.White);

        using (Graphics g2 = Graphics.FromImage(Destination))
        {
          g2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
          g2.DrawImage(Source, 0, 0, Destination.Width, Destination.Height);
        }
      }
    }

Wenn ich die g.DrawImage() Anweisung weglasse gehts, hat jemand eine Idee warum das so ist bzw. wie ich das umgehen kann?

Danke, harrylask

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von harrylask am 25.02.2010 10:17.

12.02.2010 11:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
vbprogger vbprogger ist männlich
myCSharp.de-Poweruser/ Experte

avatar-1820.gif


Dabei seit: 16.01.2006
Beiträge: 1.694
Entwicklungsumgebung: Visual Studio 2012 Prof.
Herkunft: NRW/DE


vbprogger ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

12.02.2010 11:44 Beiträge des Benutzers | zu Buddylist hinzufügen
harrylask harrylask ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.07.2005
Beiträge: 59
Herkunft: Salzburg

Themenstarter Thema begonnen von harrylask

harrylask ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Der Link hilft mir nicht weiter, ich lagere ja die Erstellung des Bitmaps in einen extra Thread aus damit mir der GUI Thread während dessen nicht blockiert wird. Er wird aber trotzdem kurz blockiert (beim Resizen, bewegen eines anderen Fensters auf der Oberfläche des GUIs). Die Ursache ist Graphics.DrawImage() die eigentlich eh im Nebenthread ausgeführt wird, warum stockt mir dann die Hauptanwendung?
12.02.2010 11:53 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.862
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

bei deinem Code fehlt irgendwie die Verwendung der Bitmaps. Was machst du mit denen denn?
12.02.2010 13:16 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
chrisdeburgh91 chrisdeburgh91 ist männlich
myCSharp.de-Mitglied

avatar-160.jpg


Dabei seit: 03.09.2009
Beiträge: 11
Entwicklungsumgebung: VS 2010, SharpDevelop


chrisdeburgh91 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

12.02.2010 13:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JAck30lena JAck30lena ist männlich
myCSharp.de-Team

avatar-2653.jpg


Dabei seit: 01.10.2006
Beiträge: 11.397
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.


JAck30lena ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Er wird aber trotzdem kurz blockiert (beim Resizen, bewegen eines anderen Fensters auf der Oberfläche des GUIs). Die Ursache ist Graphics.DrawImage() die eigentlich eh im Nebenthread ausgeführt wird, warum stockt mir dann die Hauptanwendung?

wenn es im nebenthread läuft kann die methode nciht die ursache sein... du suchst den fehler an der falschen stelle....
12.02.2010 14:36 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.478
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo harrylask,

die Frage von talla finde ich auch interessant.

Wenn es wirklich keine andere langlaufende Operation im GUI-Thread gibt, dann halte ich es für möglich, dass der Worker-Thread einfach so rechenintensiv ist, dass er dem GUI-Thread so viel Rechenzeit entzieht, dass dieser kurz "blockiert".

herbivore
12.02.2010 15:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JAck30lena JAck30lena ist männlich
myCSharp.de-Team

avatar-2653.jpg


Dabei seit: 01.10.2006
Beiträge: 11.397
Entwicklungsumgebung: Visual Studio 05/08/10 Prof.


JAck30lena ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

aber dann würden auch alle anderen anwendungen diesen hänger haben
12.02.2010 15:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.287


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab beim Threading mit Delegate.Begininvoke() auch den eindruck, dass der Threadpool träge reagiert.
Also die ersten paar male merkich eine zeitl Verzögerung, bis ein Thread rausgerückt wird, später dann nicht mehr.

Wäre eh eine Überlegung, einen NebenThread im Dauerbetrieb laufen zu lassen, oder auch gleich einen System.Timers.Timer, oder einen System.Threading.Timer zu nehmen, die ticken ja nebenläufig.
13.02.2010 08:36 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
harrylask harrylask ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.07.2005
Beiträge: 59
Herkunft: Salzburg

Themenstarter Thema begonnen von harrylask

harrylask ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

So, vorerst danke für die Hinweise.

@talla herbivore
Die Anwendung ist für einen Leitstand einer Anlage auf deren Oberfläche die Anlage selbst animiert dargestellt wird. Die Teile der Anlage liegen als Bitmaps als Resource in der Anwendung vor. In bestimmten Intervallen wird asynchron eine Methode aufgerufen die das Bitmap erstellt und je nach Auflösung skaliert.

@Allgemein
Wenn ich so wie ErfinderDesRades vorschlägt einen DauerbetriebNebenThread laufen lasse ohne der Anweisung Graphics.DrawImage() reagiert meine Hauptanwendung wie gewünscht. Füge ich aber Graphics.Draw() ein reagiert die Anwendung träge wenn sie mE irgendwas mit GDI zu tun bekommt.

Zitat:
aber dann würden auch alle anderen anwendungen diesen hänger haben

Nö, ist nicht der Fall. Alle anderen funktionieren normal.

Mein Verdacht ist das es irgendwie mit der GDI zu tun hat, hab aber keine Ahnung warum, mir fällt dazu auch keine Lösung ein wie ich das abstellen könnte. Könnt ihr das Verhalten eigentlich reproduzieren?

So long, harrylask
13.02.2010 12:52 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
harrylask harrylask ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.07.2005
Beiträge: 59
Herkunft: Salzburg

Themenstarter Thema begonnen von harrylask

harrylask ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Meine Lösung ist die das mir eine externe Anwendung mit der ich über einen IpcChannel kommuniziere das Bitmap erstellt, sämtliche Versuche die im Kontext meiner Anwendung liefen brachten den GUI Thread ins stocken.

Grüsse, harrylask
25.02.2010 10:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.287


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

ipcChannel, das heißt, hinter der property "Source" steckt ein Proxy, der erstmal über den Channel die bitmap anfordern muß?

nee, ist quatsch.

aber wennich den code jetzt angucke, wunder ich mich, dass du 2 Graphics-objekte brauchst. mit g1 löschst du die Source, mit g2 kopierst du die (gelöschte) Source nach Destination.

komisch.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ErfinderDesRades am 25.02.2010 10:40.

25.02.2010 10:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
harrylask harrylask ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.07.2005
Beiträge: 59
Herkunft: Salzburg

Themenstarter Thema begonnen von harrylask

harrylask ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo ErfinderDesRades,

Zitat:
aber wennich den code jetzt angucke, wunder ich mich, dass du 2 Graphics-objekte brauchst. mit g1 löschst du die Source, mit g2 kopierst du die (gelöschte) Source nach Destination.

Das Beispiel dient nur zum Zweck, es ist kein Originalcode. Ohne Graphics.DrawImage() ist bei mir kein Ruckeln feststellbar, mit schon.

Zitat:
ipcChannel, das heißt, hinter der property "Source" steckt ein Proxy, der erstmal über den Channel die bitmap anfordern muß?

nee, ist quatsch.

Jepp, wie würde dein Ansatz aussehen?

Grüsse, harrylask
25.02.2010 14:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 5.287


ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

ich nehme mal an, jepp heißt in diesem zusammenhang, dass tatsächlich ein proxy die bitmap ranschaffen muß.

Das holen sollte dann wohl im nebenthread geschehen, nicht im gui-thread.

und das sollte man wohl cachen, dass die nur einmal geholt wird, nicht bei jeder verwendung neu.
25.02.2010 14:36 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
harrylask harrylask ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.07.2005
Beiträge: 59
Herkunft: Salzburg

Themenstarter Thema begonnen von harrylask

harrylask ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo ErfinderDesRades,
ja, die "Serialisierung", Erstellung und "Deserialisierung" wird in einem Nebenthread gemacht, die Erstellung selbst in einer externen Applikation. Schön ist wieder was anderes aber somit bekomme ich wenigstens das lästige ruckeln weg.

Wie gesagt, sämtliche Ansätze (Threads und deren Prioritäten, AppDomains oder eine zweite MessageLoop (was ich mir von dem versprach weiss ich nicht mehr)) verliefen bei mir im Sande, das ruckeln blieb. Alles was irgendwie im Kontext meiner Anwendung lief half nicht.

Grüsse, harrylask
25.02.2010 14:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
myCSharp.de
Moderationshinweis von herbivore (27.08.2011 12:29):

Siehe auch  Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren? ff.
 
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 10 Jahre.
Der letzte Beitrag ist älter als 10 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 12.08.2020 03:46