Ich habe eine MFC-C++ - Anwendung, wo mindestens zwei Threads "MainFrame" (= GUI-Thread) und einen "Solver" -Thread ausgeführt werden.C++ Wie kann ich auslösen, dass eine PostMessage in einem anderen Thread fortgesetzt wurde
An einem Punkt löst der zweite Thread (Solver) eine Änderung im Modell aus, die der GUI-Thread durch eine PostMessage(...)
ausführen sollte. Um sicher zu sein, möchte ich warten, dass die Nachricht im zweiten Thread fortgesetzt wurde.
Mit Hilfe einer SendMessage(...)
wartet der Solver-Thread auf die Ausführung der Nachricht, aber auf diese Weise umgehen wir die Nachrichtenwarteschlange, die nicht das Ziel sein sollte.
Meine Frage: Wie kann ich richtig und sauber überprüfen/auslösen, dass meine Nachricht fortgesetzt wurde, bevor ich fortfahre?
- Müssen wir alle 'x' Sekunden den Status der Haupt-Thread-Nachrichtenwarteschlange durch
GetQueueStatus(...)
überprüfen? - Gibt es eine Möglichkeit, dass der Hauptthread ein "Erfolgsereignis" an den anderen Thread zurücksendet? Und dass der zweite wartet, um ein Ereignis zurück zu haben?
- Hat Boost eine einfache Lösung für diese Art von Problemen zur Verfügung gestellt?
- Gab es schon eine ähnliche Frage, die ich nicht gefunden habe? (Sorry)
Meine Funktion:
void PostSequencerMessageToGUI(ESequencerSignal signal, CSchedulerStep * step)
{
CMainFrame *mainFrame = theApp.GetMainFrame();
assert(mainFrame);
if (!mainFrame)
return;
mainFrame->PostMessage(WM_SEQUENCER_SIGNAL, signal, reinterpret_cast<LPARAM>(step));
// mainFrame->SendMessage(WM_SEQUENCER_SIGNAL, signal, reinterpret_cast<LPARAM>(step));
// Message was posted, now wait for event back to continue procedure
// ... but how? ...and when to cancel ? ...
return;
}
Der Fehler im Code ist. Wenn es darauf ankommt, ob eine Nachricht in die Nachrichtenwarteschlange gestellt oder direkt an die Fensterprozedur übergeben wird, haben Sie größere Probleme als diese. Wenn Sie etwas wie "PostMessage" mit einer Antwort wünschen, verwenden Sie [SendMessageCallback] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms644951.aspx). – IInspectable
Verwenden Sie einfach ein Thread-Synchronisierungsobjekt, z. B. ein Autoreset-Ereignis, das Sie mit CreateEvent erstellen. Rufen Sie SetEvent() in dem UI-Thread auf, nachdem es die Nachricht verarbeitet hat. Und WaitForSingleObject() in Ihrem Arbeitsthread. Wenn Sie auch "Erfolg" zurückgeben müssen, fügen Sie bool oder int-Member zu CSchedulerStep hinzu. –
Mit CreatEvent und SetEvent würde wahrscheinlich auch funktionieren. –