Auf Borland Thread warten funktioniert nicht



  • Hallo Leute,

    ich benutze einen Borland Thread:

    __fastcall MyThread::MyThread(bool CreateSuspended)
    	: TThread(CreateSuspended)
    {
    	FreeOnTerminate = true;
    }
    
    void __fastcall MyThread::Execute()
    {
        while(!Terminated)
        {
        // ...
        }
    }
    

    Wenn ich jetzt auf das Ende des Threads warten will klappt das nicht

    pMyThread->Terminate();
    WaitForSingleObject((HANDLE)pMyThread->Handle, INFINITE)
    

    Es wird bei WaitForSingleObject nicht gewartet so als wäre das objekt immer signalisiert. In der Dokumentation vom Borland Thread steht aber das die Eigenschaft Handle das ganz normale Handle für die WinAPI funktionen ist.

    Habt ihr irgendwelche Ideen?

    MfG



  • Ich kann das Problem im BCB 6 nicht nachvollziehen.



  • komisch ich verwende 2007

    if (pMyThread)
    {
        hThreads[ubThreadCount++] = (HANDLE)pMyThread->Handle;
        pMyThread->Terminate();
        pMyThread = NULL;
    }
    
    while (WAIT_OBJECT_0 != WaitForMultipleObjects(ubThreadCount,hThreads,true, 0))
    {
        while (::PeekMessage(&msg,0,0,0,PM_REMOVE)) ::DispatchMessage(&msg);
        ::Sleep(10);
    }
    

    und aus dieser schleife kommt er nicht raus.

    MfG



  • Diese Variante könnte schon alleine deswegen nicht funktionieren, weil möglicherweise ein oder mehrere Thread schon terminiert sind, bevor die while-Schleife überhaupt aufgerufen wird.

    Ohne konkreten Code, insbesondere des Threads, kann man dazu nichts sagen...



  • genau das ist ja der sinn der Sache in WinAPI ist das so falls sich ein Thread beendet wird sein Status auf Signalisiert gesetzt. Falls der Thread sich vor der while schleife beendet dann ist der Status signalisiert und es klappt. Mit WinAPI Threads (CreateThread) klappt dies auch ohne Probleme, jetzt habe ich nur noch einen Borland Thread hinzugefügt und mit dem gibt es halt Probleme.

    Der Thread Code steht doch oben im ersten Post.

    Wenn ich FreeOnTerminate in der Threadinitialisierung auf false setze geht es.

    FreeOnTerminate = false;
    

    Jetzt Stellt sich für mich die Frage wie Räume ich den Thread dann noch auf?
    reicht?

    pThread->Free();
    pThread = NULL;
    

    oder muß ich noch was anderes Ausführen?

    MfG



  • Destiniy schrieb:

    Wenn ich FreeOnTerminate in der Threadinitialisierung auf false setze geht es.

    Das ist nun wirklich interessant, denn im BCB 6 macht das keinen Unterschied (hatte ich vor meiner ersten Antwort schon getestet).

    Destiniy schrieb:

    Jetzt Stellt sich für mich die Frage wie Räume ich den Thread dann noch auf?

    Statt:

    pThread->Free();
    
    delete pThread;
    

    Bin mir jetzt nicht sicher, aber ->Free sollte nicht aufgerufen werden.

    Mal eine andere Frage, hast Du es schon mit TThread::WaitFor() versucht? Ich hatte bei Threads, die FreeOnTerminate = false hatten so meine Probleme damit, aber nicht wenn FreeOnTerminate = true war. Versuch mach kluch... Insgesamt hatte ich von TThread einen sehr negativen Eindruch, insbesondere was das Terminieren und warten auf Threads angeht. Ich hab die Problematik damals nur mittels eigener Win-API-Events lösen können, die praktisch als letzte Funktion des Threads in der Execute() ausgelöst wurden.



  • ja genau diesen negeativen eindruck habe ich auch. Für eine Übergangslösung habe ich auch eine eigenes Event benutzt.

    ich vermute ja wenn FreeOnTerminate = true ist dann wird das event automatisch auf signalisiert gestellt aber es kann sein das der Thread trotzdem erst später beendet wird, was dann bei mir zu problemen führt.

    ich will nicht waitfor nehmen da mein Code da ja steht ich will eigentlich auf das beenden aller Threads warten denen ich signalisiert habe "Ende Jungs" egal ob WinAPI oder Borland Thread.

    Ich benutze diesen Borland Thread mismutig, da ich aus dem Thread auf GUI Elemente Zugreife wofür ich in Borland Synchonize brauche

    Werde mal mit delete testen

    MfG


Anmelden zum Antworten