Wie richtig auf Botschaften warten


  • Mod

    Die Antwort wurde die schon gesagt. Nimm eine Message Loop!
    Die Prozessorlast wird bei einer GetMesssage/TranlateMessage/DispatchMessage Schleife nur dann extrem ansteigen, wenn dieser Thread oder ein Fenster mit Nachrichten bombardiert wird.

    Wenn Du 100% Auslastung hast, kann dies ja auch an Deinem Workerthread liegen.



  • AntonWert schrieb:

    Das Hauptprogramm "kennt" den Speicherort der Dateien. Per Button-Click startet eine Schleife mit FindFirstFile / FindNextFile und sucht nach Diesen Dateien (das sind unter umständen mehrere tausend Stück). Somit ist mein Hauptprogramm aber in dieser Schleife "gefangen"

    Starte einen weiteren Thread für die Suche nach den Dateien, so daß sich das Hauptprogramm ausschließlich um die GUI kümmern kann.



  • AntonWert schrieb:

    Das Hauptprogramm "kennt" den Speicherort der Dateien. Per Button-Click startet eine Schleife mit FindFirstFile / FindNextFile und sucht nach Diesen Dateien (das sind unter umständen mehrere tausend Stück). Somit ist mein Hauptprogramm aber in dieser Schleife "gefangen" 😞

    Warum startet dein Hauptprogramm, nicht einen Workingthread der sowohl das Finden, als auch das Auswerten der Dateinen übernimmt. Solange die Auswertung stattfindet, braucht doch eigentlich keine neue Datei gefunden werden, die verarbeitet werden muß. Erst wenn die Datei verarbeitet wurde, macht er sich auf die Suche nach einer weiteren Datei die deinem Kriterium entspricht. Das würde dann auch wieder deinern Aussage "könnte sich der Inhalt im laufe der Verarbeitung noch ändern." entgegen kommen. Solange der Working-Thread arbeitet, deaktiviert du den Button für die Suche und aktivierst vieleicht einen Button für "Abbrechen" der eine globale Variabele setzt. Diese Variable kannst du dann im Workingthread an verschiedenen Programmstellen abfragen und den Workingthread sauber beenden.



  • @Helmut:
    Diese Idee hatte ich mir schon öfters überlegt, aber dennoch verworfen.
    Ich würde z.B. die aktuelle Datei welche bewarbeitet wird anzeigen, und die kann ich irgendwie ja nicht durch eine Windows-Botschaft schicken - oder geht sowas? Mein Hauptprogramm kann ja bereits auf Botschaften des Threads hören, aber das sind eben nur "int"-Daten.


  • Mod

    Du könntest den Namen in einem Feld ablegen und über eine Critical-Section ablegen. Du könntest dann eine Nachricht senden, die über die Änderung den Main-Thread informiert.



  • Ja das geht, du kannst z.B. in deiner WM_COMMAND Message für LPARAM einen Pointer auf CHAR schicken und dein Eventhandler wertet diesen aus und zeigt den String an (beachte hierbei ob der String Null terminiert ist).
    Oder du legst dir eine globale Struktur an. Dein Workingthread füllt diese Struktur mit Informationen über den momentanen Zustand, z.B. Dateiname, Dateigröße, Dateiinhalt, Protzentangabe und was immer du da noch reinpacken möchtest. Dann musst du nicht mal einen Pointer mit WM_COMMAND mitschicken, weil die Struktur ja global ist. Es empfield sich dann ein Flag einzubauen, das vom Hauptthread gesetzt wird wenn dieser die Nachricht erhalten hat, wenn der Hauptthread das Flag noch nicht gesetzt hat, dann gilt für den Workingthread, daß die Struktur schreibgeschützt ist. Dies wäre eine Möglichket.
    Wenn du aber kein Freind von globalen Variablen bist, dann kannst du die Struktur in deinem Workingthread anlegen und einen Pointer auf die Struktur über WM_COMMAND schicken.


  • Mod

    @*helmut*
    1. Muss man dazu keine WM_COMMAND Nachricht verwenden. Besser eine eigene definierte Nachricht (WM_APP+x oder RegisterMessage)
    2. Sollte man bei Zeigern nur SendMessage verwenden, PostMessage geht nicht, denn man kann nicht für die Gültigkeit des Zeigers garantieren.
    3. SendMessage hat den Nachteil einer erzwungenen Threadsynchronisation.

    Ich würde einen Storage reservieren und diesen mit einer Ctrical Section absichern.



  • Hallo,

    ich hab für mich nun eine Lösung gefunden. Die Idee mit der globalen Struktur find ich in diesem Fall am bessten.
    Der Thread legt die aktuellen Informationen in die Struktur, das Hauptprogramm erstellt daraus eine brauchbare Anzeige.

    Vielen Dank für die Hilfen.


  • Mod

    Nur noch mal als Anmerkung:
    Da lesend und schreibend auf die Daten zugegriffen werden musst Du diese über eine Ctrical Section absichern.



  • Martin Richter schrieb:

    Nur noch mal als Anmerkung:
    Da lesend und schreibend auf die Daten zugegriffen werden musst Du diese über eine Ctrical Section absichern.

    Dazu hab ich eine Frage. Muß so eine Situation immer über eine Critical Section abgesichert werden, oder kann man davon ausgehen, dass bei diesem Anwendungsfall (nur eine Prozentangabe die durch des Hauptthread aktualisiert wird) es auch zuverlässig ohne eine Critical Section realisiert werden kann?

    Was kann in dem konkreten Fall passieren, wenn die Schreib-/Lesebereiche nicht über eine Critical Section abgesichert werden. Einen Deadlock zum Beispiel kann ich mir erst mal nicht vorstellen.



  • daimonion schrieb:

    Martin Richter schrieb:

    Nur noch mal als Anmerkung:
    Da lesend und schreibend auf die Daten zugegriffen werden musst Du diese über eine Ctrical Section absichern.

    Was kann in dem konkreten Fall passieren, wenn die Schreib-/Lesebereiche nicht über eine Critical Section abgesichert werden.

    Der lesende Thread kann inkonsistente Daten bekommen, weil der schreibende Thread nach dem Schreiben eines Teils der Daten unterbrochen werden kann.


  • Mod

    Solange es sich nur um einen einzigen 32bit Wert handelt ist dies wohl ausgeschlossen...



  • Belli schrieb:

    Der lesende Thread kann inkonsistente Daten bekommen, weil der schreibende Thread nach dem Schreiben eines Teils der Daten unterbrochen werden kann.

    Okay, das macht Sinn, wenn mehrere Daten geschrieben werden. Danke für die Antwort.


Anmelden zum Antworten