Filou Geschrieben 25. September 2006 Geschrieben 25. September 2006 Hi, ich möchte ein kleines Tool machen, dass die Werte einer Datenbank ausließt und überprüft. Dazu habe ich einen Start-Button im Dialog, eine Progressbar und eine Statusanzeige (Text). Wenn man jetzt auf start klickt soll das ganze loslegen. Im Momment ist es so, dass dann ein Thread gestartet wird, der wiederum Funktionen aufruft welche die Datenbank auslesen und auswerten. Mein Problem ist jetzt, dass nach einer gewissen Zeit (paar Sek) nach Programmstart der Dialog einfriert. Also "Anwendung reagiert nicht". Trotzdem läuft das Programm weiter und nach ein paar Sekunden wird das Ergebnis angezeigt. Wie baue ich mein Programm so auf, dass der Dialog nicht einfriert? Ich das müsste mit einem Thread gehen... Könnt ihr mir da weiterhelfen? Gruß Filou
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Zeig mal den Thread und wie du ihn startest.
Filou Geschrieben 25. September 2006 Autor Geschrieben 25. September 2006 //Thread starten CWinThread *pThread = AfxBeginThread ( DBStart, this, THREAD_PRIORITY_NORMAL); m_bStart = TRUE; while(m_bStart == TRUE) { //Progressbar m_Progressbar.SetRange(0,m_iGesAnz); m_Progressbar.SetPos(m_iCurrentPos); m_csFehlermeldung = g_csFehlermeldung; UpdateData(FALSE); Sleep(100); }
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Mit dieser while-Schleife blockierst du die Nachrichtenverarbeitung in deinem Dialog.
Filou Geschrieben 25. September 2006 Autor Geschrieben 25. September 2006 Aber ich muss ja irgendwie die Progressbar und den Text aktualisieren. Weil wenn ich innerhalb des Threads "UpdateData" aufrufe, knallts. Wie geht das denn anders?
Guybrush Threepwood Geschrieben 25. September 2006 Geschrieben 25. September 2006 Schick aus deinem Thread die entsprechenden Änderungen per SendMessage an die Progressbar.
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Aber ich muss ja irgendwie die Progressbar und den Text aktualisieren.Dann lass den Thread doch eine Nachricht an den Dialog posten, wenn es etwas zu aktualisieren gibt. Das hatten wir doch irgendwie schon ein paar Mal, wenn ich mich richtig erinnere
Filou Geschrieben 25. September 2006 Autor Geschrieben 25. September 2006 Ja da hast Du recht! Das hatten wir schonmal mit PosteMessage... Hab nochmal nachgeschaut in meim anderen Projekt und jetzt klappt es auch. Allerdings stürzt das Programm ab wenn ich es beenden will. Woran kann das liegen? OnCancle wird aufgerufen, nachdem der Thread komplett durchgelaufen ist. Hab auch schon was mit TerminateThread(hThread,1000); versucht, ging aber auch nicht... :confused: void CDBCheckUpDlg::OnCancel() { m_bStart = FALSE; Sleep(1500); this->EndDialog(9); }
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Einfache Variablen und Sleep sind für Threadsynchronisation nicht geeignet. Benutz ein Event und warte hinter auf das Threadhandle.
Filou Geschrieben 25. September 2006 Autor Geschrieben 25. September 2006 Einfache Variablen und Sleep sind für Threadsynchronisation nicht geeignet. Benutz ein Event und warte hinter auf das Threadhandle. Hmm ich versteh nicht genau... Das hier ist mein Thread: UINT DBStart(LPVOID pParam) { CDBCheckUpDlg *pWnd; pWnd=(CDBCheckUpDlg*)pParam; pWnd->Start(); return (0); } In der Funktion Start werden die einzelnen Schritte aufgerufen und gaaaanz am ende dann OnCancle(). Das heißr. dann ist der Thread doch automatisch beendet, oder? Was soll ich da vorhr mit dem Event machen? Wie geht das?
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 In der Funktion Start werden die einzelnen Schritte aufgerufen und gaaaanz am ende dann OnCancle()Das heißt, du rufst eine MFC-Methode aus einem anderen Thread als dem, der das Objekt erstellt hat, auf. Das ist schon mal falsch. Was soll ich da vorhr mit dem Event machen? Wie geht das?Momentan signalisierst du dem Thread über eine Boolvariable, dass er sich beenden soll. Das ist nicht zuverlässig. Statt dessen sollst du ein Event benutzen. Der Thread wartet regelmäßig (z.B. in der Schleife) mit Timeout 0 auf das Event und beendet sich, wenn es signalisiert ist. Stichworte: CreateEvent, SetEvent, WaitForSingleObject. Nachdem das Event gesetzt wurde, kannst du mit WaitForSingleObject auf das Threadhandle warten, bis der Thread wirklich beendet ist.
Filou Geschrieben 25. September 2006 Autor Geschrieben 25. September 2006 Das m_bStart wird nicht mehr verwendet. Das hab ich raus gemacht. Der Thread läuft einfach durch und soll am Ende sich selbst und den Dialog beenden. Aber ich versuche es mal mit dem Event... (hoffe ich bekomms hin )
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Der Thread läuft einfach durch und soll am Ende sich selbst und den Dialog beenden.Der Thread darf den Dialog nicht direkt beenden. Du könntest dafür auch eine benutzerdefinierte Nachricht benutzen.
Filou Geschrieben 25. September 2006 Autor Geschrieben 25. September 2006 Ich habe es jetzt mit PostMessage gemacht, dass der Dialog beendet wird. Es stürtzt in der Datei "DAOCORE.CPP" an dieser Stelle ab: if (m_pICDAORecordsetGetRows != NULL) { m_pICDAORecordsetGetRows->Release(); m_pICDAORecordsetGetRows = NULL; } Die Datenbank schließe ich aber vorher. Liegt das immernoch am Thread?
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren
Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde Dich hier an.
Jetzt anmelden