Hi,
ich habe folgendes Problem:
Ein Hauptprogramm erstellt ein Statusfenster. Das Hauptprogramm erstellt desweiteren einen neuen Thread, der eine längere Berechnung ausführt. Währenddessen wartet das Hauptprogramm auf die Terminierung des Threads mit WaitForSingleObject(xxx,INFINITE).
Der Thread gibt nun Daten an das Statusfenster, die angezeigt werden sollen. Das Problem ist nun aber, das die CPU nie für das Hauptprogramm rechnet (wartet ja auf das Ende des Threads…), und somit das Statusfenster nicht aktualisieren kann.
Besteht eine andere Möglichkeit, als mit einem parallelen Thread der das Statusfenster bedient, diesen Fehler zu umgehen?
Vielen Dank
Philipp
Hi Philipp,
ich habe ein paar Fragen: Erzeugst Du den Thread mit AfxBeginThread? Wenn ja, erstellst Du einen Worker-Thread oder einen Userinterface-Thread? Ist Dein Statusfenster ein CWnd-Objekt?
Vielleicht postest Du einfach mal den Code, der das Fenster und den Thread erstellt.
Gruß
Uwe
[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]
ich habe ein paar Fragen: Erzeugst Du den Thread mit
AfxBeginThread? Wenn ja, erstellst Du einen Worker-Thread oder
einen Userinterface-Thread? Ist Dein Statusfenster ein
CWnd-Objekt?
Vielleicht postest Du einfach mal den Code, der das Fenster
und den Thread erstellt.
Gruß
Uwe
Hm, die Befehle kenn ich nicht (bin in dem Gebiet kein Experte…). Ich verwende die Befehle der Windows-Api in der Borland 5.02 Umgebung:
*************************************************
Thread erschaffen:
HANDLE hMutex = CreateMutex(NULL,false,„MyName“);
HANDLE hMutex_2;
DuplicateHandle(GetCurrentProcess(),hMutex,
GetCurrentProcess(),&hMutex_2,
0,false,DUPLICATE_SAME_ACCESS);
HANDLE myThread = CreateThread(NULL,0,ThreadFunktion,
LPVOID lpParameter,DWORD dwCreationFlags,
LPDWORD lpThreadId);
Hauptprogramm wartet so:
WaitForSingleObject(myThread,INFINITE);
*************************************************
Dialog wird so erstellt:
p_Dlg = new My_Dlg(this, idd, 0);
p_Dlg->Create();
p_Dlg->ShowWindow(SW_SHOW);
//dann hier die Threadberechnung mit Datenanzeige
und so gelöscht:
p_Dlg->CmCancel();
delete p_Dlg;
Grüße
Philipp
Tja, leider habe ich noch nie mit dem Builder gearbeitet. Ich kenne mich nur mit MFC unter VisualC aus. Und selbst da stecken meine Erfahrungen mit Thread-Programmierung noch in den Kinderschuhen.
Ich kann Dir also nur sagen, wie ich es unter MFC angehen würde:
-
Möglichkeit: Windows-Messages
Für das Statusfenster wird eine eigene Fensterklasse erstellt, die User-definierte Windows-Messages empfängt. Der Arbeitsthread schickt eine Nachricht an das Statusfenster, das entsprechend der Nachricht reagiert (z.B. eine Prozentanzeige akualisiert oder einen Button aktiviert/deaktiviert).
Damit der Thread weiß, an welches Fenster er seine Nachrichten verschickt, wird dem Thread beim Start der Handle des Statusfensters übergeben.
-
Möglichkeit: Direkte Zugriffe auf das Statusfenster
Wieder wird dem Thread beim Start der Handle des Statusfensters übergeben. Aber in diesem Fall steuert der Worker-Thread das Fenster nicht über Messages, sondern greift direkt auf die Elemente und Methoden der Statusfensterklasse zu.
Vielleicht gibt Dir das einen kleinen Anhaltspunkt, wo Du ansetzen kannst. Ich hoffe, ich konnte Dir wenigstens ein wenig helfen.
Gruß, und viel Erfolg!
Uwe
[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]
…ich machs so :
Hi Uwe,
wo erzeugst Du das Statusfenster ? Im Hauptprogram ?
Ich würd das Statusfenster dem 2.Thread bekannt machen, dann kann dieser direkt Status- oder Fortschrittsmeldungen an das Statusfenster weitergeben.
Wenn der Status gar nix mit dem Hauptprogramm zu tun hat, soll p_Dlg im Thread erzeugt, upgedatet und auch wieder vernichtet werden, bevor der Thread sich selbst schliesst. Das Hauptprogramm macht währenddessen gar nix, bzw. wartet auf das Beeenden des Thread.
Gruss
Hans
[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]
wo erzeugst Du das Statusfenster ? Im Hauptprogram ?
Ja
Ich würd das Statusfenster dem 2.Thread bekannt machen, dann
kann dieser direkt Status- oder Fortschrittsmeldungen an das
Statusfenster weitergeben.
Ist schon geschehen. Handle wird übergeben…
Wenn der Status gar nix mit dem Hauptprogramm zu tun hat, soll
p_Dlg im Thread erzeugt, upgedatet und auch wieder vernichtet
werden, bevor der Thread sich selbst schliesst. Das
Hauptprogramm macht währenddessen gar nix, bzw. wartet auf das
Beeenden des Thread.
Siehe unteren Abschnitt.
Gruss
Hans
Hi Hans
Tja, das Problem ist (hab ich leider vergessen zu erwähnen), dass ich mit dem Fenster auch Botschaften verarbeiten muss (Cancel-Button z.B.). Wie soll ich aber das Fenster schließen, wenn der Thread in Berechnungen vertieft ist? Er wird nicht auf das Event reagieren, da er ja noch mit der Ausführung von Code beschäftigt ist. Meiner Meinung nach bleibt mir als einzige Möglichkeit einen eigenen Thread für das Statusfenster zu erstellen, der dann aufgrund der Zeitscheiben in der Verfassung wäre, auf den Button-Event zu reageren.
Oder gibt es eine andere - elegantere Methode?
Gruß
Philipp
Tja, leider habe ich noch nie mit dem Builder gearbeitet. Ich
kenne mich nur mit MFC unter VisualC aus. Und selbst da
stecken meine Erfahrungen mit Thread-Programmierung noch in
den Kinderschuhen.
Ich kann Dir also nur sagen, wie ich es unter MFC angehen
würde:
-
Möglichkeit: Windows-Messages
Für das Statusfenster wird eine eigene Fensterklasse erstellt,
die User-definierte Windows-Messages empfängt. Der
Arbeitsthread schickt eine Nachricht an das Statusfenster, das
entsprechend der Nachricht reagiert (z.B. eine Prozentanzeige
akualisiert oder einen Button aktiviert/deaktiviert).
Damit der Thread weiß, an welches Fenster er seine Nachrichten
verschickt, wird dem Thread beim Start der Handle des
Statusfensters übergeben.
-
Möglichkeit: Direkte Zugriffe auf das Statusfenster
Wieder wird dem Thread beim Start der Handle des
Statusfensters übergeben. Aber in diesem Fall steuert der
Worker-Thread das Fenster nicht über Messages, sondern greift
direkt auf die Elemente und Methoden der Statusfensterklasse
zu.
Ja, ich denke, dass der 2.Teil die richtige Lösung ist (für meinen Fall). Und das Statusfenster wird mit einem eigenen Thread erzeugt, damit es Meldungen von einem Button-Event verarbeiten kann, auch wenn der Thread für Berechnungen viel zu tun hat…
Oder liege ich da falsch?
Vielleicht gibt Dir das einen kleinen Anhaltspunkt, wo Du
ansetzen kannst. Ich hoffe, ich konnte Dir wenigstens ein
wenig helfen.
Vielen Dank!!
Philipp
Gruß, und viel Erfolg!
Uwe