Problem mit Dynamisch angelgten Threads



  • Ich lege mit diesem Code die Threads Dynamisch an :

    Jeder Thread soll einfach nur ein packet an einen Server per UDP senden und eine Antwort abwarten. Kommt eine Antwort werden die Daten gesplittet und in einem ListView eingefügt. Synchronize benutze ich, daran kanns nicht liegen. Ich benutze sogar innerhalb der von Synchronitze aufgerufenen Funktion eine CriticalSection. Obwohl ich glaube das dies sinnlos ist da Synchronize diese bereits macht.

    thrdArray.Length = ServerListe->Count;    //Anzahl kann mehrer 100 enthalten
    
        int i=0;
    
        for(i;i<thrdArray.Length;i++)
        {
            thrdArray[i] = new TJoinerThread(false,lvGameSpy->Items->Item[i],i);
            thrdArray[i]->FreeOnTerminate = true;
        }
    

    Ich habe auch folgende version beim Aufruf probiert :

    thrdArray.Length = ServerListe->Count;
    
        int i=0;
    
        for(i;i<thrdArray.Length;i++)
        {
            thrdArray[i] = new TJoinerThread(true,lvGameSpy->Items->Item[i],i);
            thrdArray[i]->FreeOnTerminate = true;
            thrdArray[i]->Resume();
        }
    

    Und es tritt immer noch eine AccessViolation beim beenden des Programms auf.

    Meine Execute Funktion :

    void __fastcall TJoinerThread::Execute()
    {
        //---- Hier den Thread-Code plazieren----
    
        while(DEAD == false)
        {
            if(!Send)
            {
                Send = true;
            }
            else if(Terminated == false && Send == true)
            {
                Application->ProcessMessages();
                DEAD = true;            
            }
        }
    }
    //---------------------------------------------------------------------------
    

    Ich habe den Code im Thread praktisch auf NULL reduziert, trotzdem bekomme ich Fehler wenn ich die Anzahl der Threads höher als 3 anlege.
    Selbst dann kommt es auch vor das ich eine Meldung bekomme, aber nicht so häufig.

    Ich erhalte eine EInvalidPointer Meldung.
    Wenn ich die Anwendung ausserhalb des BCB ausführe bekomme cih hintereinander ein Paar Meldungen und zuletzt eine Abnomal Programm Termination.


  • Mod

    Hallo

    hast du schonmal

    thrdArray.Length = ServerListe->Count;
    

    an eine andere Stelle geschrieben
    zB nach new

    Mfg
    Klaus 🕶



  • Hi,
    Application->ProcessMessages();

    würd ich nicht in der Execute-Methode einbauen. Der Thread Wartet dann bis alle anstehende Messages der Anwendung abgearbeitet wurden. Das macht die Sache wieder Syncron.

    Ansonsten haben wir zu wenig Informationen um das Problem zu lösen. Der Code sieht soweit recht gut aus.
    Ich weiss aber nciht wo der Fehler auftritt und wie die Klasse TJoinerThread aufgebaut ist. Liegt der Fehler vielleicht in Teile des COdes, den du nicvht gepostet hast ?

    makiere bitte die Zeile, in der die Fehler auftreten.
    ICh hab kein BCB auf dem Rechner und kanns somit nicht selbst ausprobieren.

    hm, sollte den BCB mal wieder installieren 🙄



  • Im Prinzip ist das der ganze Code.

    Wie ich geschrieben habe, habe ich praktisch NULL Code der ausgeführt wird.

    ich habe fast den gesamten Code auskommentiert, somit sollte dieser keine Rolle spielen und schon garnicht die Fehler produzieren.

    Die Zeile mit dem Fehler kann ich leider nicht posten, da ich vom Debugger keinen Punkt erhalte wo dieser Fehler herkommt.

    Ich weiss nur soviel das die Schleife zum erzeugen der Threads durchlaufen wird und wie ebenfalls geschrieben, erst wenn ich die Anzahl der Threads auf mehr als 2 oder 3 stelle erhalte ich diese Fehler.
    Oft habe ich auch Zugriffs Fehler auf Adresse 000000.

    Ich denke mal das bei der Freigabe der Threads irgendwas durcheinander kommt.

    Selbst wenn ich in der Execute des Threads nur Send = true; mach also praktisch sofort wieder den thread beende kommt so ein Fehler.

    @KlausB
    Was meinst Du mit nach new ?
    Hinter dem erzeugen der Threads ist wohl kaum möglich da ich vor eintritt in die Schleife ja wissen muss wieviele ich brauche.

    Endschuldigt meine Unwissenheit aber muss ich das Array auch mit New initialisieren ? Aus der FAQ ist das nicht ersichtlich und auch in der Hilfe ist diese nicht so gemacht.

    Ich habe mir nochmal das Beispiel dort wird geschrieben das es eine wietere möglichkeit mit TList gibt.

    meint Ihr ich könnte das mal so probieren oder sollte ich lieber TObjectList benutzen ?



  • So ich habe es jetzt nochmal mit einer TList versucht, klappt aber auch nicht so richtig.

    Hier mal der Code der wichtigsten Funktionen.

    Hier erzeuge ich die Threads.

    /* Die TList ist natürlich im Header mit TList *thrdList angelegt */
    
        int i=0;
        thrdList = new TList;
        TJoinerThread *gsThread;
        thrdList->Capacity = ServerListe->Count;
    
        for(i=0;i<thrdList->Capacity;i++)
        {
            gsThread = new TJoinerThread(false,lvGameSpy->Items->Item[i],i);
            gsThread->OnTerminate = DeleteThread;
            thrdList->Add(gsThread);
        }
    

    Die Funktion von OnTerminate habe ich momentan Leer.

    Hier die Funktion zum freigeben der Threads bei OnClose des Programmes

    void __fastcall TFMain::FormClose(TObject *Sender, TCloseAction &Action)
    {
        TIniFile *ini;
        ini = new TIniFile(GetIniFile());
    
        ini->WriteInteger("App", "Close", rgClose->ItemIndex);
        if(thrdList != NULL)
        {
            for(int i=0;i<thrdList->Count;i++)
            {
                thrdList->Delete(i);
            }
            delete thrdList;
        }
        delete ini;
        delete List;
    
    }
    

    Beim Austritt aus dem OnClose bekomme ich eine Zugriffs verletzung.

    Hier nochmal der aufs minimum beschränkte Code in der Execute

    void __fastcall TJoinerThread::Execute()
    {
        while(DEAD == false)
        {
            Sleep(500);
            DEAD = true;
        }
    }
    

    Im Constructor des Threads mache ich nurnoch

    __fastcall TJoinerThread::TJoinerThread(bool CreateSuspended, TListItem *LstItem, int Index)
        : TThread(CreateSuspended)
    {
        DEAD = false;
        FreeOnTerminate = true;
    }
    


  • versuche den Fehler mit try -catch-Blöcken einzugrenzen. Gib sinnvolle Fehlermeldungen und Positionen aus.

    Deine Liste müsste auch gehen. Du kannst aber auch ruhig mal ne TList ausprobieren.


Anmelden zum Antworten