Threads richtig öffnen und schliessen



  • Hi

    ich hab ein Problem, das mein Thread entweder im Hauptdialog funktioniert oder nur vom Hauptdialog aufgerufenen Dialog.

    Sobald mein Programm started wird im OnInitDialog ein Thread gestartet welcher denn ComPort überwacht. Diesen Thread stoppe bzw. beende ich wenn ich in meinem Hauptdialog denn Konfigurationsdialog öffne. Im Konfigurationsdialog starte ich wieder einen Thread und schliesse denn Thread wenn das Dialog beendet wird. Schliesslich wird der Thread im Hauptdialog wieder gestarted.

    Das komische ist das der Thread nur im Hauptdialog funktioniert und immer noch funktioniert wenn ich ihn wieder starte nachdem ich Dialog2 geschlossen habe. Jedoch funktioniert der Thread für Dialog2 nicht. Genauso ist es umgekehrt das wenn ich denn Thread im Hauptdialog nie starte, der Thread in Dialog 2 dann funktioniert.

    Thread Start Methode:

    //
    // start comm watching
    //
    BOOL CSerialPort::StartMonitoring()
    {
    
    	if (!(m_Thread = AfxBeginThread(CommThread, this)))
    		return FALSE;  [i][b]//Starte Thread[/b][/i]
    	TRACE("Thread started\n");
    	return TRUE;	
    }
    

    Thread Stop Methode:

    //
    // Suspend the comm thread
    //
    BOOL CSerialPort::StopMonitoring()
    {
    	CloseHandle(m_hComm); [i][b]//Schliesse ComPort, gebe ComPort frei[/b][/i]
    	m_Thread->SuspendThread(); [b]//Stoppe Thread[/b]
    	TRACE("Thread suspended\n");
    	return TRUE;	
    }
    

    Aufruf:

    StartMonitoring(); //Starte Thread;
    

    Stoppe Thread und starte Dialog:

    m_Ports[0].StopMonitoring(); [i][b]//stop comport (Scanner) monitoring[/b][/i]
    
    	CAddItemDlg* addItemDlg = new CAddItemDlg(this);
    	addItemDlg->DoModal();
    
    	m_Ports[0].StartMonitoring();[i][b] //start scanner comport monitoring[/b][/i]
    

    Hilfe bitte helfen.. 😞



  • wenn du einen thread von neuem startest muss man das mit AfxBeginThread
    machen, das ist richtig

    wenn du ihn zwischendurch stoppen willst mit suspendThread()
    auch richtig

    aber wenn du den gleichen wieder starten willst mit resumeThread()

    in deinem beispiel legst du immer wieder einen neuen thread an

    der aufruf im zweiten dialog seh ich leider hier nicht.also weiß ich nciht was da falsch sein kann



  • im zweiten dialog rufe ich genaus denn Thread wie im Hauptdialog und schliesse ihn auch genauso. ausserdem kann ich ja bei resume eines Threads ja nicht angeben wer jetzt das Parent Window ist 😕 oder?

    das mit resume thread weiss ich. Jedoch wenn ich resume thread im zweiten Dialog aufrufe reagiert er im ersten Dialog und nicht im zweiten Dialog.

    z.B. ich hab ein Kassensystem, Thread wird gestarted welcher ComPort auf ein Scan vorgang wartet, bis ein Produkt eingescannt wird und fügt schliesslich das Produkt in die ListBox. Existiert das Produkt (Barcode) nicht in der Datenbank, rufe ich z.B. mit der Taste F6 ein Dialog auf mit dem ich ein neues Produkt anlegen kann. Dazu muss ich doch im ersten Dialog die überwachung ausschliessen und denn Thread stoppen. Mach ich ein ResumeThread im 2.ten Dialog dann reagiert im Hintergrund der Hauptdialog und das möchte ich nicht.

    Es muss doch irgendwie zu gehen sein. Schliessen und das komplette LÖSCHEN einse Threads muss doch möglich sein. Dann dürfte doch kein Problem entstehen. Nur wie.

    Bin total verzweifelt.



  • gib mir mal das coding wie du das im zweiten dialog aufrufst

    das richtige beenden geht ja nicht mit dieser methode sondern mit afxendthread()



  • wäre super wenn du mein problem lösen könntest. hänge schon seit wochen und kommme nicht weiter. also.. die methoden habe ich oben schon erläutert.

    wenn ich F8 drücke wird der Thread im Hauptdialog beendet und ein Dialog2 aufgerufen und nachdem der Dialog2 geschlossen wird dieser Thread wieder gestarted, das macht diese Methode:

    void CKasseDlg::OnProduktverwaltungNeuesprodukteinf()
    {
    	m_Ports[0].StopMonitoring(); //stop comport (Scanner) monitoring
    
    	CAddItemDlg* addItemDlg = new CAddItemDlg(this);
    	addItemDlg->DoModal();
    
    	[b]m_Ports[0].StartMonitoring(); //start scanner comport monitoring again[/b]
    }
    

    danach in OnInitDialog vom Dialog2 wird Thread und der ComPort intialisiert:

    // init the ports
    	if (m_Ports[0].InitPort(this, 1, 9600, 'N',8,1,EV_RXCHAR,512))
             //start Thread
    	m_Ports[0].StartMonitoring();
    

    danach mache ich meine Eingabe und drücke ok übernhem die Werte und beende denn Thread von diesem Dialog:

    //stop monitor com port thread
    			m_Ports[0].StopMonitoring();
    

    wie gesagt funktioniert nur ein Thread entweder im Haupt dialog oder in dem aufgerufenen Dialog2. Ich kommentiere denn code jeweils für denn Dialog aus. Dann geht das andere. 😕

    ich hoffe so sehr das du mir helfen kannst. WÄRE SUPER 😋



  • also das m_ports in deiner dialog2 klasse ist das das gleiche objekt das im hauptfenster verwendet wird? oder sind zwei unterschiedliche?



  • es existiert einmal im
    Hauptdialog und einmal im Dialog 2

    Die Thread Klasse habe jeweils in beide Klassen des Dialogs importiert und in der Klasse des jeweiligen Dialogs ein Objekt erzeugt.



  • ok wenn das wirklich so ist, dann versteh ich das problem nicht mehr, weil dann beide threads voneinander unabhängig sind.

    sind aber schon worker threads oder?



  • worker threads ?

    ja aber kann es daran liegen das jeweils beide threads einen zugriff auf denn ComPort machen, diesen intialisieren und schliessen ? Jedoch müsste eigentlich nichts passieren dar ich ja mit

    m_Port[0].stopMonitoring();

    denn Thread ja stoppe und auch denn handel zum ComPort schliesse. Deshalb darf hier doch kein Problem entstehen. Ausserdem wenn beid Threads startbereit sind funktioniert der 2.te Thread nur wenn ich im Debug modus bin. Schliese ich denn Dialog 2 dann bekomme ich ich eine Fehlermeldung an der stelle bei der Methode stopMonotoring() ... m->SuspendThread() manchmal auch über ComPort1.

    Kann es sein das ich evtl. eine warteschleife brauche bevor ich denn einen Thread schliesse und denn anderen starte, damit genug zeit für das schliessen und öffnen des comports gewährleistet ist ?? Wenn ja wie mache ich das ??

    Mann ich bin am Arsch... 😮



  • es gibt methoden die darauf schauen ob die threads wirklich beendet wurden

    und wie ich ja schon gesagt habe, darst du nicht nur suspendthread machen
    sonder du musst AFXENDTHREAD aufrufen, das gegenstück zum afxbeginthread()

    ich denke mal schon das du einen worker thread gebaut hast 🙂

    beim schließen deines dialoges solltest du auf alle fälle den AfxEndThread aufrufen. sonst hängt der doch immer noch in der prozessschleife



  • void AFXAPI AfxEndThread(
    UINT nExitCode,
    BOOL bDelete = TRUE
    );

    Parameters
    nExitCode
    Specifies the exit code of the thread.

    hmm... kann ja mal probieren jedoch wie bekomme ich denn nExitCode damit AfxEndThread auch mitbekommt welcher thread es ist ? In der CWinThread klasse habe ich nichts gefunden welches mir den ExitCode eines Threads zurückliefert.

    gruss
    Indian



  • Call this function to terminate the currently executing thread.

    du musst das nur aufrufen,den exit code bekommst du ja um zu wissen ob es gut ging.



  • du musst kein exit code angeben, den bekommst du zurück.
    musst mal in der msdn gucken was für was steht

    0 ist glaub ich succeeded



  • AfxEndThread(UINT nExitCode,BOOL bDelete = TRUE);

    laut definition siehe oben verlangt AfxEndThread UINT nExitCode :p

    hier der Beweis

    c:\Dokumente und Einstellungen\Administrator\Eigene Dateien\Visual Studio Projects\Kasse\Kasse\SerialPort.cpp(488): error C2660: 'AfxEndThread' : function does not take 0 parameters
    

    ausserdem wird AfxEndThread nicht innerhalb des Threads aufgerufen ??? Ich hab doch keinen Zugriff auf dem Thread. Ich will ihn doch von aussen schliessen d.h. wenn ich F8 drücke jedoch ist der Thread ja ne Endschlossschleife welcher in von einer anderen Klasse eingebunden wurde der nur denn ComPort überwacht. Mit AfxEndThread würde der Thread nur einmal fragen ob was am ComPort anliegt. Was hab ich dann davon AfxEndThread aufzurufen welcher doch den ExitCode verlangt. Bekomme immer ne Fehlermeldung.



  • natürlich musst die variable mitgeben, das das eine output variable ist.
    ist doch logisch 😃



  • AfxEndThread bringt nichts .. man kann es nur innerhalb des Threads aufrufen. Macht leider null sinn 😞



  • finde einfach kein Beispiel wie ich AfxEndThread verwenden kann.

    Ob es in dem Fall überhaupt auch interessant ist ? Kann es ja nur innerhalb aufrufen.

    Mist glaub nicht das ich es irgendwann noch löse.. Ich lauf amok



  • les das mal Multithreading: Terminating Threads

    in der msdn


Anmelden zum Antworten