Threads und keine klaren Infos dazu im Netz....
-
1. Rückgabewert von AfxBeginThread kann NULL sein.
2. DerThread der mit AfxBeginThread gestartet wird kann schon beendet sein, bevor Du m_bAutoDelete FALSE setzt. Also AfxBeginThread suspended starten, dann m_bAutoDelete FALSE setzen, dann Thread resumen.
3. Das Event existiert nicht wenn Du ResetEvent machst. Erzeuge das Event befor, der Thread erzeugt wird.
4. Wenn Du auf den Thread warten willst nimm den Zeiger und das Handle das Du von AfxBeginThread bekommst und nimm nicht ein eiegnes Event.
-
Wie machst du denn den Datenbankzugriff? Ich kenns nur so, dass die Abfrage sich selbst um den Connect kümmert. Damit dürfetn die Zugriffsverletzungen nicht von der DB-Abfrage kommen. Sowas ist immer schwer zu finden, da es nicht immer auftritt und bei Threads (so ist meine Erfahrung) fast immer am Design das Aufbaus umd den Threadaufruf drum herum liegt.
Was passiert, wenn die Funktion zweimal mit function == StartThread aufgerufen wird? Hast du das irgendwie geblockt? Dann dürfte es auch scheppern. Es scheint ja so als ob das ein Funktionsrumpf einer OnButton-Methode ist, oder sehe ich das falsch?
Mit den Events scheint auch was nicht zu stimmen? Du machst ein Reset, obwohl das Create da noch nicht aufgerufen sein muss. Also ich blick das nicht ganz was du dir da gedacht hast.+
-
Martin Richter schrieb:
1. Rückgabewert von AfxBeginThread kann NULL sein.
2. DerThread der mit AfxBeginThread gestartet wird kann schon beendet sein, bevor Du m_bAutoDelete FALSE setzt. Also AfxBeginThread suspended starten, dann m_bAutoDelete FALSE setzen, dann Thread resumen.
3. Das Event existiert nicht wenn Du ResetEvent machst. Erzeuge das Event befor, der Thread erzeugt wird.
4. Wenn Du auf den Thread warten willst nimm den Zeiger und das Handle das Du von AfxBeginThread bekommst und nimm nicht ein eiegnes Event.Danke fuer die Antwort! Ihr seid super

Also ich hab das mal n bisschen veraendert! Das mit dem Suspended hab ich nicht so ganz gerafft, aber hab was dazu im Internet gefunden und das ganze nun so veraendert!
UINT UpdateThread(LPVOID pParam) { ZuErstelleneKlasse *Klasse = reinterpret_cast<ZuErstelleneKlasse*>(pParam); while(1){ ResetEvent(g_hThreadEvent); //g_hThreadEvent = globaler Handler Klasse->ReadData(); //Daten lesen vom Server SetEvent(g_hThreadEvent); if(g_bFlagEndThread){ return 1; } } } //Memberfunktion - StartThread,StopThread und WaitThread ueber #define int MainDialog::ThreadStartStop(int function) { if(function == StartThread){ g_bFlagEndThread = 0; SetEvent(g_hThreadEvent); //Thread wird erstellt, aber noch nicht gestartet m_CWTThreadpointer = AfxBeginThread(&UpdateThread,this, THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL); if(m_CWTThreadpointer == NULL){ MessageBox("Fehlermeldung....blabla"); //beende Programm...etc } m_CWTThreadpointer->m_bAutoDelete = FALSE; //Starte den Thread ResumeThread(m_CWTThreadpointer->m_hThread); } else if(function == StopThread){ g_hThreadEvent = CreateEvent(NULL,FALSE,FALSE,NULL); g_bFlagEndThread = 1; WaitForSingleObject(g_hThreadEvent,INFINITE); delete m_CWTThreadpointer; } else if(function == WaitThread){ //optional!!! SuspendThread(m_CWTThreadpointer->m_hThread); } else if(function == RestartThread){ ResumeThread(m_CWTThreadpointer->m_hThread); } else{ return 0; } return 1; }@AndyDD: Ich erstelle direkt am Anfang eine Verbindung und beim beenden des Programms wird dieses wieder beendet. Wenn das Programm lauft werden parallel zum eigentlichen Dialog (ueber den Updatehread) immer wieder Daten geholt und in ein globales Array geschrieben, auf das wiederrum der Hauptdialog zugreift. Das funktioniert auch soweit wunderbar!
Wenn ich zweimal ThreadStartStop(StartThread) aufrufe, koennte ich ein problem haben....aber ansich ist es nicht moeglich, dass es zwei mal aufgerufen wird (es sei denn, ich setze es irgendwo faelschlicherweise nochmal hin, was ich eigentlich nicht vor hatte)
Momentan steht in der OnInitDialog() das ThreadStartStop(StartThread) und in der OnCancel das ThreadStartStop(StopThread). Falls ich auf die Idee kommen sollte denn Thread zwischendurch anzuhalten, wollte ich das ueber die ThreadStartStop(WaitThread) machen!
-
Mit dem suspend bedeutet, dass du die Threadinstanz anlegst, den Thread aber noch nicht laufen lässt. Der Grund für das Vorgehen ist folgender: sollten die Threadfunktion auf Grund zeitunkritischer Aufgaben (z.B. du machst nur ne Instanzierung einer Variablen und weist der einen Wert zu (was innerhalb eines Workerthreads totaler Quatsch wäre)) bereits abgearbeitet worden sein, wäre es theoretisch möglich, dass du es laufzeittechnisch nicht schaffst, m_bAutoDelete auf false zu setzen, da ja der Thread bereits returniert ist und sich womöglich schon selbst gekillt hat. Somit sollte man, auch wenn es vermeintlich nicht vokommt (weil du z.b. im Thread ne Endlosschleife hast), diese Eventualität berücksichtigen.
Benutzername_ schrieb:
@AndyDD: Ich erstelle direkt am Anfang eine Verbindung und beim beenden des Programms wird dieses wieder beendet. Wenn das Programm lauft werden parallel zum eigentlichen Dialog (ueber den Updatehread) immer wieder Daten geholt und in ein globales Array geschrieben, auf das wiederrum der Hauptdialog zugreift. Das funktioniert auch soweit wunderbar!
Wenn ich zweimal ThreadStartStop(StartThread) aufrufe, koennte ich ein problem haben....aber ansich ist es nicht moeglich, dass es zwei mal aufgerufen wird (es sei denn, ich setze es irgendwo faelschlicherweise nochmal hin, was ich eigentlich nicht vor hatte)
Momentan steht in der OnInitDialog() das ThreadStartStop(StartThread) und in der OnCancel das ThreadStartStop(StopThread). Falls ich auf die Idee kommen sollte denn Thread zwischendurch anzuhalten, wollte ich das ueber die ThreadStartStop(WaitThread) machen!Das Gleiche gilt für das hier. Auch wenn du es nicht vorgesehen hast, könnte es sein, deine Funktion wird in irgendeiner Weise von Framework automatisch aufgerufen. Ich bin auch schon mal über sowas gestolpert. Deshalb solltest du immer absichern, dass wenn ein Thread läuft er nicht nochmal gestartet werden kann. Weiterhin kapiere ich deine Umgehensweise mit der Datenbank nicht ganz. Wie ist die denn angebunden? Via ODBC oder ADO? Aber beide Mechanismen connecten nur, wenn die Daten manipulieren oder abrufen. Meist wird der Connect vom Framework gemacht (dafür gibts eigens Klassen), dann wird die entsprechende Datenmenge von der Datenbank abgerufen, manipuliert und wieder zurückgeschrieben und der Connect unterbrochen. Also versteh ich dein Problem nicht ganz.
-
Zugriff auf Daten einer SPS via OLE!
Die Verbindung wird die ganze Zeit aufrecht erhalten. Die Abfrage der Daten soll so oft wie moeglich gemacht werden, wobei dieses aber immer ein paar 100 Millisekunden dauert. Haette ich keinen extra Thread zum abfragen, bleibt das Programm fuer diese Zeit stehen. Deshalb die Erstellung des Threads und die Klasse->ReadSync() Anweisung.
-
Mist...wenn ich das richtig sehe, wird der Thread immer noch nicht richtig beendet! Momentan bekomme ich ab und zu ein "Unhandled exception in System.exe(MFC42D.DLL): 0xC00000005: Access Violation"
LRESULT CALLBACK _AfxMsgFilterHook(int code, WPARAM wParam, LPARAM lParam) { CWinThrad* pThread; if (afxContextIsDLL || (code < 0 && code != MSGF_DDEMGR) || (pThread = AfxGetThread()) == NULL) { return ::CallNextHookEx(_afxThradState->m_hHookOldMsgFilter,code, wParam, lParam); } ASSERT(pThread != NULL); return (LRESULT)pThread->ProcessMesageFilter(code, (LPMSG)lParam);//<== }Liegt das daran, dass der Thread (noch) nicht richtig beendet wurde?!
Kann mir jemand helfen?! Was ist falsch an dem Code (siehe drei Eintraege vorher)?!?!

Diese Thread bringen mich langsam zur Verzweifelung...das kann doch nicht so schwer sein, vedammt!!
-
Das Programm stoppt beim zweiten Return, dort wo der Pfeil ist!
-
Benutzername_ schrieb:
Zugriff auf Daten einer SPS via OLE!
Die Verbindung wird die ganze Zeit aufrecht erhalten. Die Abfrage der Daten soll so oft wie moeglich gemacht werden, wobei dieses aber immer ein paar 100 Millisekunden dauert. Haette ich keinen extra Thread zum abfragen, bleibt das Programm fuer diese Zeit stehen. Deshalb die Erstellung des Threads und die Klasse->ReadSync() Anweisung.Also schreibt die SPS die Daten in eine Datenbank und du fragst die ab? Aber selbst wenn du OLE unter MFC verwendest, dann connectet die OLE-DB-Consumer-Klasse die Datenbank nur, wenn die Daten liest oder schreibt.
Kann es sein das dein Programm in Zeile 10 stoppt? Da wird ja geprüft, ob der Thread noch existent ist. Wenn du Martins Hinweise befolgst dürfte es problemlos laufen. Hast du das schon so umgesetzt?
-
Martin Richter schrieb:
4. Wenn Du auf den Thread warten willst nimm den Zeiger und das Handle das Du von AfxBeginThread bekommst und nimm nicht ein eiegnes Event.
Du meinst das hier, richtig?! Ich werd's gleich mal testen!
Thx!
-
Ich meine CWinThread::m_hThread
-
Benutzername_ schrieb:
Martin Richter schrieb:
4. Wenn Du auf den Thread warten willst nimm den Zeiger und das Handle das Du von AfxBeginThread bekommst und nimm nicht ein eiegnes Event.
Du meinst das hier, richtig?! Ich werd's gleich mal testen!
Thx!
Ja klar, oder meinst du wir geben dir diese Tipps zum Spass?
-
AndyDD schrieb:
Benutzername_ schrieb:
Martin Richter schrieb:
4. Wenn Du auf den Thread warten willst nimm den Zeiger und das Handle das Du von AfxBeginThread bekommst und nimm nicht ein eiegnes Event.
Du meinst das hier, richtig?! Ich werd's gleich mal testen!
Thx!
Ja klar, oder meinst du wir geben dir diese Tipps zum Spass?
Okay, okay! Danke dafür! Läuft....