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 Zitieren
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Zeig mal den Thread und wie du ihn startest. Zitieren
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); } Zitieren
Klotzkopp Geschrieben 25. September 2006 Geschrieben 25. September 2006 Mit dieser while-Schleife blockierst du die Nachrichtenverarbeitung in deinem Dialog. Zitieren
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? Zitieren
Guybrush Threepwood Geschrieben 25. September 2006 Geschrieben 25. September 2006 Schick aus deinem Thread die entsprechenden Änderungen per SendMessage an die Progressbar. Zitieren
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 Zitieren
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); } Zitieren
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. Zitieren
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? Zitieren
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. Zitieren
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 ) Zitieren
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. Zitieren
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? Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.