Thread mit MessageHandler



  • Hallo,

    ich möchte einen Thread mit eigenem MessageHandler erzeugen. Dazu gibt es ja die sog. UI-Threads. Allerdings brauche ich keine Dialoge in diesem Thread.

    Ich will nun wissen wie ich einen Thread dort starte.
    Bei reinen Workerthreads ist es klar weil dort mittels AfxBeginThread die Funktion angegeben wird.

    In der von CWinThread abgeleiteten Klasse kann ich keinen Hinweis finden wie ich meinen Prozessfunktion starte. Wird das in InitInstance() erledigt oder sollte ich diese Threadfunktion als public deklarieren und von aussen einfach aufrufen?

    BOOL MyProcess::InitInstance()
    {
        // TODO:  Initialisierung hier durchführen und Threads verwenden
        // return TRUE;
    
        return Thread_MyProcessFunction();
    }
    

    Gestartet werden soll von aussen via Buttonklick:

    m_pProcessAutomatic = dynamic_cast <ProcessAutomatic*> (AfxBeginThread(RUNTIME_CLASS(ProcessAutomatic), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL));
    if (m_pProcessAutomatic == NULL)
    	{
    		AfxMessageBox("Thread ProcessAutomatic konnte nicht erzeugt werden!", MB_ICONERROR);
    		return;
    	}
    
    m_pProcessAutomatic->setObjects(objekte);
    m_pProcessAutomatic->ResumeThread();
    
    // Moeglickeit 2: Hier Threadfunktion aufrufen
    m_pProcessAutomatic->Thread_MyProcessFunction();
    

  • Mod

    Wenn Du in InitInsatnce ein Fenster erzeugst und auch ein Fenster hast, dann sollte die Existenz dieses Fensters auch die Lebenszeit des Threads steuern.
    m_pMainWnd wird dann in CWinThread gesetzt.

    Ansonsten mach alles in InitInstance und verlassen die Funktion mit FALSE!

    Dir steht es auch frei CWinThread::Run zu überschrieben. Dort läuft normalerweise die MessageLoop!



  • Hmm Ok,

    ich habe jetzt mal den Thread in InitInstance aufgerufen.

    Wie sendet man eine Message an den Thread?

    Von aussen mit

    PostThreadMessage (m_pProcessAutomatic->m_nThreadID, WMU_MESSY, 0, true);
    

    und dann im Thread? ON_THREAD_MESSAGE gibt C2440.

    Gibts hier nur den Umweg über PreTranslateMessage?


  • Mod

    Wenn Du eine Thread Message bearbeiten willst must Du auch eine Message Loop haben!



  • Hat man das nicht automatisch? Schließlich ist das doch der Unterschied zum Workerthread, daß UI-Threads das MessageHandling inklusive haben.

    Muß man das doch selbst implementieren? Dummerweise startet das MessageHandler System erst nach InitInstance().
    Müßte man dann Run überladen, in diesem die Prozess_state_maschine abarbeiten und in dieser immer mit GetMessage, Dispatch, ect. zuerst die Messies behandeln? 😮



  • Ich sehe gerade, dass man am besten ein unsichtbares GUI vom Thread erzeugen laesst und dieses dann von aussen mit PostMessage füttert.
    Auf diesem Wege würden keine Messies verloren gehen.
    Naja wieder mal ein toller Workaround... 😞 😡


  • Mod

    Du hast das Messagehandling nur automatisch wenn Du auch in die Run Loop reingehst.



  • Und wie würde das gehen?
    Run überladen und in dieser mein State-Maschine Loop ablaufen lassen ohne dabei

    CWinThread::Run()
    

    aufzurufen?

    Ich steh grad total aufm Schlauch. 😞


  • Mod

    Habe ich doch geschrieben. Einfach aus InitInstance mit TRUE rausgehen. Dann läuft Run...

    Schau doch in den Sourcecode.



  • Moin,

    ja das hab ich verstanden aber das hilft mir nicht für das was ich will.

    Mein Maschinenprozess läuft in einer Prozedur ab. Bisher taten es dafür Workerthreads. Da aber nun dem Workerthread Ereignisse mitgeteilt werden müssen kann ich dann keinen Workerthread mehr verwenden da dieser keine MessagePump hat. Folglich muss ich ne C von CWinThread ableiten und in diesem die Prozedur einbauen. Aber wie starte ich diesen wenn die MPump aktiviert sein soll?

    * Rufe ich das in IInst auf und gehe anschließend mit false (autodelete = true) raus, sodaß es keine MLeaks gibt, hab ich keinen MHandler. Ergo: dasselbe wie Workerthread.

    * Verlasse ich IInst mit true läuft Run und ich habe eine MPump. Dann aber versagt der Aufruf der Threadprozedur weil dieser nicht parallel läuft. Siehe Code im Startpost. MLeaks gibts dann auch weil ich nicht weiß wann und wo ich aufräumen soll, schließlich gibts kein Fenster das ich zerstören könnte.



  • Nachtrag:

    Wäre es sinnvoller gleich nen Workerthread zu nehmen, da dieser von außen nur auf 2 boolsche reagieren muß?
    PostMessage vom Thread raus klappt ja auch in WThreads.


  • Mod

    Du missverstehst hier etwas.
    Ein UI Thread ist eben wie der Mainthread.
    Wenn Du eine endlose Schleife baust, dann gibt es keine Nachrichtenschleife, wenn Du eine Nachrichtenschleife hast, dann kannst Du nur zwischendrin was machen.

    Du kannst nicht "eine Threadprozedur" + "parallele Messagepump" haben.

    Es gibt CWinThread::OnIdle, wenn keine Nachricht anliegt kannst Du hier was machen. Solange Du nicht zurückkommst gibt es auch keinen Messagepump...

    ExitInstance gibt es auch...
    Wenn Du Nachrichten empfangen willst benötigst Du ein Fenster.

    Wie immer wird eine Nachrichtenschleife durch PostQuitMessage oder das zerstören des primären Fensters beendet.

    Wenn Leaks Du hast, räumst Du eben nicht korrekt auf.
    Was für Leaks hast Du?

    Was in CWinThread passiert ist egnau das was in CWinApp auch passiert.



  • Ich werde es mit einem Workerthread realisieren. UI Threads sind das falsche.

    Danke für die Hilfe.


Anmelden zum Antworten