kathi008 Geschrieben 12. März 2008 Geschrieben 12. März 2008 Hallo Forum... hab folgendes Problem: hab eine MFC-EXE Anwendung mit FormView und mehreren Threads die beim Klick auf VerbindenButton in der Form nacheinander Starten... funktioniert soweit... Wenn ich die Verbindung mit dem Button trenne und die Anwendung beende--> is ok Allerdings wenn ich die Anwendung mit dem Schliessen Kreuz beende, wird das Fenster sofort zerstört, aber der letzte Thread nicht beendet... Meine Farage: Wie kann den Thread beendetn bzw. auf das Beenden warten, hab schon mit WaitForMultipleObjects bzw. WaitForSingleObject versucht, aber irgendwie wartet die Anwendung nicht, hab schon ein Array mit Thread-Handles angelegt, um zu sehen, welche Threadsnoch aktiv sind. Ein Thread hat dann immer Status STILL_ACTIVE, wenn ich den zwingend schliessen will mit TerminateThread() kommt ein Errorcode 6 --> Invalid Handle Was soll ich tun??? Zitieren
Klotzkopp Geschrieben 12. März 2008 Geschrieben 12. März 2008 Wie startest du die Threads überhaupt? Wie kann den Thread beendetn bzw. auf das Beenden warten, Üblicherweise setzt man ein Event, dass der Thread regelmäßig prüft. TerminateThread ist eine Notbremse, die wirklich nur in absoluten Ausnahmefällen zum Einsatz kommen sollte. hab schon mit WaitForMultipleObjects bzw. WaitForSingleObject versucht, aber irgendwie wartet die Anwendung nicht,Was heißt "wartet nicht"? Mit welchem Wert kommt WaitForSingleObject denn zurück? wenn ich den zwingend schliessen will mit TerminateThread() kommt ein Errorcode 6 --> Invalid Handle Das lässt eher vermuten, dass beim Speichern der Handles schon etwas schief geht. Auch hier wäre ein wenig Code hilfreich. Zitieren
kathi008 Geschrieben 13. März 2008 Autor Geschrieben 13. März 2008 Das Programm ist so aufgebaut: es sind mehrere Threads, die laufen aber nie gleichzeitig, je nach Aktion des Benutzers wird einer oder anderer gestartet, und wenn der fertig ist wird der nächster gestartet usw... Ich starte die Threads so: AfxBeginThread(ThreadFunc,this); Die ThreadFunk: UINT CDT05View::ThreadFunc(LPVOID param) { CDT05View* pAppView = (CDT05View*)param; if(modus == 1) { pAppView -> doThreadEvents1(); return 0; } if(modus == 2) { pAppView -> doThreadEvents2(); return 0; } //usw... return 1; }[/PHP] Üblicherweise setzt man ein Event, dass der Thread regelmäßig prüft. Wie mache ich das? Zitat von kathi008 hab schon mit WaitForMultipleObjects bzw. WaitForSingleObject versucht, aber irgendwie wartet die Anwendung nicht, Also ich glaub es wartet schon, nur es ist so: Die Thread sind in der FormView, da es die AusgabeThreads sind, diese greifen immer auf die Steuerelemente der FormView zu... nun wenn ich die Anwendung mit dem SchließenKreuz beende wird das Fenster zerstört, aber der Thread, der gerade irgendwo inmitten der Schleife ist wird nicht gestoppt...und beenden kann ich das nach dem Zerstören des Fensters auch nicht, anscheinend existiert es auch nicht mehr... nur das es noch paar PostMessages an das Fenster kommen, wo es zu Assertion kommt, was auch klar ist... Meine Frage war: Kann ich irgendwie das Zerstören des Fensters abfangen, dass ich das Thread ordentlich beenden kann bzw. bis es die Schleife abgearbeitet hat und von selber schliesst...? Hab mit PostNCDestroy versucht, aber da ist das Fenster nicht mehr da... und OnClose greift noch später... Hab Zwischenlösung gefunden: ich deaktiviere das SchließenKreuz, so das der Nutzer gezwungen wird die Verbindung bzw. das Thread mit dem Button zu beenden, erst dann wird das Kreuz wieder aktiv:rolleyes: Zitieren
Klotzkopp Geschrieben 13. März 2008 Geschrieben 13. März 2008 Ich starte die Threads so: AfxBeginThread(ThreadFunc,this);Und woher holst du dir das Threadhandle, auf das du warten willst, wenn du hier den Rückgabewert wegwirfst? Wie mache ich das?Schau dir mal CEvent und CSingleLock an. Also ich glaub es wartet schon,Du "glaubst"? Warum beantwortest du nicht meine Frage nach dem Rückgabewert? Die Thread sind in der FormView, da es die AusgabeThreads sind, diese greifen immer auf die Steuerelemente der FormView zu...Da ist schon der Ansatz schlecht. Auf Fenster darf nur aus dem Thread zugegriffen werden, der sie auch erzeugt hat. Deine Worker-Threads (denn solche startest du, wenn du AfxBeginThread so benutzt) haben von allen Fenstern die Finger zu lassen. Schick Nachrichten an den Fensterthread, und lass den auf die Fenster zugreifen. Meine Frage war: Kann ich irgendwie das Zerstören des Fensters abfangen, dass ich das Thread ordentlich beenden kann bzw. bis es die Schleife abgearbeitet hat und von selber schliesst...? Hab mit PostNCDestroy versucht, aber da ist das Fenster nicht mehr da... und OnClose greift noch später...OnClose ist schon richtig. Das sollte auch vor jedem OnDestroy aufgerufen werden. Immerhin kannst du in OnClose das Schließen noch verhindern. Zitieren
kathi008 Geschrieben 14. März 2008 Autor Geschrieben 14. März 2008 Und woher holst du dir das Threadhandle, auf das du warten willst, wenn du hier den Rückgabewert wegwirfst? So habe ich es am Anfang gemacht, als ich dann das Problem beheben wollte hab ich es so aufgerufen: cwnd = AfxBeginThread(ThreadFunc,this); pAktiveThread[1] = cwnd->m_hThread; [/PHP] Der Handle von dem Thread liefert STILL_ACTIVE (259) Der Rückgabewert der Funktion WaitForMultipleObjects() ist 0xFFFFFFFF und GetLastError lierfert 6, also Invalid Handle--> nehme an, dass es daran liegt dass das Fenster nicht mehr existiert und der Thread dementsprechen auch... ich danke dir für die schnellen Antworten, ich werde mein Programmkonzept noch mal komplett überdenken müssen:rolleyes:, das es nicht direkt auf die FormView greift... und die CEvent und CSingleLock schau ich mir auch noch genau an... ich sag bescheid, wenn ich es geschaft habe:hells:... wird aber warscheinlich eine Weile dauern... 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.