Thread schneller ausführen oder Alternative gesucht



  • @yahendrik sagte in Thread schneller ausführen oder Alternative gesucht:

    Ich würde zunächst mal prüfen, ob die Anzahl vielleicht nicht begrenzt werden kann. Millionen von Items gleichzeitig anzuzeigen und den Anwender dort eine sinnvolle Auswahl treffen zu lassen, halte ich nicht unbedingt für benutzerfreundlich.

    Gebe ich dir recht. Mein Programm ist erstmal nicht für den produktiven Gebrauch gedacht, sondern lediglich eine Testanwendung die mir hilft die Funktionsweise und Bedienbarkeit eines OwnerDraw Listview besser zu verstehen. Ich spiele hier mal so alle Varianten durch die man mit Items in einem Report-Listview so anstellen kann, z.B. einfügen, löschen, verschieben, sortieren, markieren, drag-and-drop, etc.. und das Ganze eben mit einer sehr großen Anzahl an Items um zu sehen wie sich das Programm zeitlich verhält.

    @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    Fix: Definiere eine eigene Message der du den Start-Index mitgibst sowie einen Zeiger auf ein Array wo sie die Resultate reinschreiben darf und die grösse dieses Arrays. Und falls du mehr als eine solche ListView hast natürlich das ListView Handle. Der Message Handler schreibt dann die angegebene Anzahl an ausgewählten Elementen (Indexen) in das Array und gibt zurück wie viele er geschrieben hat.

    hustbaer, Danke! Wie so oft kommt von dir ein super Lösungsvorschlag. Ich hab einen Thread gestartet der mir die Controls blockiert, die erstmal nicht bedienbar sein dürfen. Dann am Ende des Threads per PostMessage(...) die Anforderung an dem Thread im Hauptfenster schickt. Dort wird die eigendliche Arbeits-Funktion gestartet, am Ende der Arbeits-Funktion (je 10.000 Items werden verarbeitet) wird geprüft ob noch unbehandelte Items übrig sind, wenn ja wieder ein PostMessage(...) zum Aufruf der Arbeits-Funktion, wenn nein, Fertig. Ja was soll ich sagen die Ausführung als User dauert nun nur noch 1,330 Sekunden, also nur unwesentlich länger als die vorher blockierende Funktion. Da ich wahrscheinlich nie mit 1.000.000 Items arbeiten werde, ist die jetzige Lösung für mich perfekt.



  • @yahendrik sagte in Thread schneller ausführen oder Alternative gesucht:

    Millionen von Items gleichzeitig anzuzeigen und den Anwender dort eine sinnvolle Auswahl treffen zu lassen, halte ich nicht unbedingt für benutzerfreundlich.

    Ich finde das nicht unbedingt verkehrt. So lang man sehr schnell/effizient filtern und sortieren kann, finde ich das in Ordnung. Da würde ich z.B. Paging eher verwirrend finden. Was bringt es mir, wenn ich eine Leiste mit 1-1000 Seiten sehe? Ich muss doch dann genauso filtern oder zum ersten Buchstaben springen können usw. Das geht mit einer Ansicht mit 1 Mio Einträgen genauso, aber ohne das sinnlose Paging.
    Wenn das aber ein technisches Problem ist (z.B. tatsächlich 1 Mio Einträge aus der Datenbank holen und verarbeiten, die man sonst nicht brauchen würde), ist das natürlich was anderes.



  • @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    Was Admin vs. normalen User angeht: Windows hat einige Security-Checks eingebaut, auch bei den GUI Funktionen.

    Ja, ein User Programm darf auf jeden Fall keine Nachrichten an ein Programm schicken, das mit Admin Rechten läuft. Vielleicht nicht mal an ein Fenster eines anderen Benutzers, das weiß ich nicht.
    Aber es ist schon interessant, wieviel das auszumachen scheint. Und wie sie das dann überhaupt implementiert haben...



  • @Oxigen sagte in Thread schneller ausführen oder Alternative gesucht:

    @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    Fix: Definiere eine eigene Message der du den Start-Index mitgibst sowie einen Zeiger auf ein Array wo sie die Resultate reinschreiben darf und die grösse dieses Arrays. Und falls du mehr als eine solche ListView hast natürlich das ListView Handle. Der Message Handler schreibt dann die angegebene Anzahl an ausgewählten Elementen (Indexen) in das Array und gibt zurück wie viele er geschrieben hat.

    hustbaer, Danke! Wie so oft kommt von dir ein super Lösungsvorschlag. Ich hab einen Thread gestartet der mir die Controls blockiert, die erstmal nicht bedienbar sein dürfen. Dann am Ende des Threads per PostMessage(...) die Anforderung an dem Thread im Hauptfenster schickt. Dort wird die eigendliche Arbeits-Funktion gestartet, am Ende der Arbeits-Funktion (je 10.000 Items werden verarbeitet) wird geprüft ob noch unbehandelte Items übrig sind, wenn ja wieder ein PostMessage(...) zum Aufruf der Arbeits-Funktion, wenn nein, Fertig. Ja was soll ich sagen die Ausführung als User dauert nun nur noch 1,330 Sekunden, also nur unwesentlich länger als die vorher blockierende Funktion. Da ich wahrscheinlich nie mit 1.000.000 Items arbeiten werde, ist die jetzige Lösung für mich perfekt.

    Bitte 🙂
    Ich hab zwar nicht den Eindruck dass ich in letzter Zeit besonders viel super Lösungsvorschläge poste, aber wenn du das so wahrnimmst freut es micht.

    Klingt gut. Nur ... dann brauchst du ja eigentlich überhaupt keinen extra Thread mehr, oder? Also du könntest den ersten Teil (Controls blocken und erste Message posten) dann ja auch gleich im GUI Thread machen. Nicht?



  • @Mechanics Zwischen User und anderem User ist glaub ich auch nicht erlaubt. Was mich ein wenig wundert ist dass es auch einen Unterschied macht wenn alles mit dem selben User nur im GUI Thread läuft. Ich hätte mir erwartet dass es da einen fast-path gibt so dass der Check für genau diesen Fall sehr schnell mit "alles OK" beendet werden kann. Aber vielleicht ist das doch nicht so einfach machbar wie ich es mir vorstelle 🙂



  • @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    Ich hab zwar nicht den Eindruck dass ich in letzter Zeit besonders viel super Lösungsvorschläge poste, aber wenn du das so wahrnimmst freut es micht.

    Habe früher als unregistrierter User hier einiges angefragt, da hattes du mir oft schon geholfen. Daher lese ich immer genau durch was du zum Thema weist.

    @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    Klingt gut. Nur ... dann brauchst du ja eigentlich überhaupt keinen extra Thread mehr, oder? Also du könntest den ersten Teil (Controls blocken und erste Message posten) dann ja auch gleich im GUI Thread machen. Nicht?

    Liegt vielleicht daran wie ich die Messages der Controlls blockiere. Damit "Controll-funktioniert-gerade-nicht" für den User auch sichtbar ist, deaktiviere ich das Controll per "EnableWindow(..., FALSE)"als allererstes in meiner Arbeitsfunktion, am Ende wenn die Arbeit getan ist wird wieder eingeschaltet " "EnableWindow(..., TRUE)". Wenn ich das nicht über einen separaten Thread mache, dann sind die Controlls während der Arbeitsfunktiion zwar nicht bedienbar, aber leider werden sie auch nicht ausgegraut, sondern augenscheinlich aktiv dargestellt. K.A. vielleich mach ich da was falsch?



  • @Oxigen sagte in Thread schneller ausführen oder Alternative gesucht:

    Wenn ich das nicht über einen separaten Thread mache, dann sind die Controlls während der Arbeitsfunktiion zwar nicht bedienbar, aber leider werden sie auch nicht ausgegraut, sondern augenscheinlich aktiv dargestellt. K.A. vielleich mach ich da was falsch?

    Naja die erste Arbeitsfunktion blockiert dann ja nur die Controls und postet die Message und dann geht's weiter. Das ist schnell erledigt. Und dann sollte das mit dem Ausgrauen auch funktionieren.



  • @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    Naja die erste Arbeitsfunktion blockiert dann ja nur die Controls und postet die Message und dann geht's weiter. Das ist schnell erledigt. Und dann sollte das mit dem Ausgrauen auch funktionieren.

    Ja das ist wohl war, ist mir auch schon in den Sinn gekommen. Ich hab mal drüber nachgedacht, wie oft ich schon in meinen Programmen die Controls so deaktiviert habe. Oh Mann, da könnten vieleicht einige Sachen flotter laufen. Naja in Zukunft werde ich das dann so machen. Mal schauen habe bestimmmt 2 -3 Programme, die ich auch nacharbeiten sollte.



  • BTW: Was ich nicht weiss: wann WM_PAINT Nachrichten genau abgearbeitet werden. Was ich mich erinnere haben die relativ niedrige Priorität, d.h. es könnte sein dass die erst drankommen wenn keine selbst geposteten Nachrichten mehr da sind.
    (Also genaugenommen sind WM_PAINT glaube ich gar nie in der Queue sondern werden erzeugt wenn nix "wichtigeres" mehr ansteht und die Dirty-Region nicht leer ist. Aber was als "wichtiger" gilt weiss ich nimmer.)

    Anyway, falls du solche Probleme hast und die GUI trotz Aufteilung auf mehrere gepostete Messages immer noch einfriert: um sowas kann man mit Timern rumarbeiten. Einfach einen Timer mit Timeout 0 starten. Der wird dann erst bearbeitet wenn es sonst überhaupt nix mehr zu tun gibt, und dort kann man dann seine "Background-Tasks" machen. Und wenn man fertig ist, den Timer einfach wieder löschen - weil er ja sonst dauern feuern und die CPU auf 100% bringen würde.



  • @hustbaer sagte in Thread schneller ausführen oder Alternative gesucht:

    WM_PAINT

    OK, hab nachgesehen:

    The system sends this message when there are no other messages in the application's message queue.

    Also... wird vermutlich mit dem Messages posten trotzdem einfrieren. Also das Fenster rumschieben sollte schon gehen, klicken vermutlich auch, aber es könnte sein dass die GUI nicht mehr refresht bis die PostMessage-Orgie fertig ist. Aber möglicherweise reicht das auch so für dich.



  • Das müsste auch mittels InvalidateRect/UpdateWindow bzw. RedrawWindow (mit passenden Parametern) gehen (s.a die Antworten in Difference between InvalidateRect and RedrawWindow).


Anmelden zum Antworten