Hängender Prozess im Thread-Programm



  • Hallo zusammen !

    Ich habe mit einer NMFTP-Komponente ein kleines FTP-Download-Programm geschrieben, das sämtliche Dateien auf einem Server herunterlädt. Zuerst habe ich es mit einem seriellen Download-Aufruf der einzelnen Dateien probiert, dies hat sich aber als sehr langwierig erwiesen. Jetzt benutze ich für jede Datei einen eigenen Connection-Thread und das funzt eigentlich sehr gut und ist wesentlich schneller. Leider kommt es ab und zu vor, dass das Programm nach dem laden der Dateiliste vom FTP-Server sich einfach aufhängt. Das heisst, dass die einzelnen Threads nicht gestartet werden. Leider kann ich mir darauf keinen Reim machen.

    Vielleicht weiß ja jemand von Euch bescheid...

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
            strDestPath = ParamStr(1);                    // Zielverzeichnis als Parameter
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormActivate(TObject *Sender)
    {
            String Host = "www.xyz.com";
            String User = "xyz";
            String Pass = "xyz";
    
            if (ParamCount() != 0) {
    
                    Label1->Caption = "Es werden nun die Online-Bestellungen vom FTP-Server geholt - Bitte warten ... ";
    
                    FTPList = new TStringList();
    
                    NMFTP1->Host = Host;
                    NMFTP1->UserID = User;
                    NMFTP1->Password = Pass;
                    NMFTP1->Port = 21;
                    NMFTP1->Passive = true;
    
                    try {
                            NMFTP1->Connect();
                            NMFTP1->Nlist();
                            NMFTP1->Disconnect();
    
                            if (FTPList->Count == 0) {
                                    MessageBox(NULL, "Es sind keine Bestellungen auf dem FTP-Server vorhanden !", "Meldung", MB_OK);
    
                                    Close();
                                    return;
                            }
    
                            TThread* thread;
    
                            for (int iIndex = 0; iIndex < FTPList->Count; iIndex++) {
                                    TNMFTP* NMFTP = new TNMFTP(this);
                                    NMFTP->Host = Host;
                                    NMFTP->UserID = User;
                                    NMFTP->Password = Pass;
                                    NMFTP->Port = 21;
                                    NMFTP->Passive = true;
                                    NMFTP->Connect();
                                    NMFTP->Mode(MODE_BYTE);
    
                                    String strDestination = strDestPath + FTPList->Strings[iIndex];
                                    thread = new DownloadThread(NMFTP, FTPList->Strings[iIndex], strDestination);
                            }
    
                            while (thread->WaitFor() != 1) {}
                    }
                    catch (...) {
                            MessageBox(NULL, "Es konnte keine Verbindung hergestellt werden !", "Meldung", MB_OK);
                    }
            }
    
            Close();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::NMFTP1ListItem(AnsiString Listing)
    {
            FTPList->Add(Listing);
            iOrderCount++;
    
            Label2->Caption = iOrderCount;
            Label2->Refresh();
    }
    //---------------------------------------------------------------------------
    

    Die Thread-Routine sieht folgendermaßen aus:

    //---------------------------------------------------------------------------
    
    __fastcall DownloadThread::DownloadThread(TNMFTP* NMFTP, String FileName, String DestPath)
            : TThread(false)
    {
            NMFTP1 = NMFTP;
            strFileName = FileName;
            strDestPath = DestPath;
    
            this->ReturnValue = 0;
    }
    //---------------------------------------------------------------------------
    void __fastcall DownloadThread::Execute()
    {
            NMFTP1->Download(strFileName, strDestPath);
    //        NMFTP1->Delete(strFileName);
            NMFTP1->Disconnect();
    
            this->ReturnValue = 1;
    }
    //---------------------------------------------------------------------------
    

    Best Dank für die Hilfe...

    Gruß MacReeg



  • Hallo zusammen !

    Ich glaube meine Vermutung, dass das Programm deswegen "hängen" bleibt, weil die Connection-Threads gestartet werden obwohl nicht gesichert war, dass die erste Connection zum FTP-Server noch nicht beendet wurden, scheint sich zu bewahrheiten. Nach folgender Code-Ergänzung scheint das Programm nicht mehr mit dem oben genannten Problem behaftet zu sein:

    ...
    
                    try {
                            NMFTP1->Connect();
                            NMFTP1->Nlist();
    
                            while (NMFTP1->Connected) {
                                    NMFTP1->Disconnect();
                            }
    		...
    

    Weiterhin habe ich festgestellt, dass das Programm bei einer begrenzten Bandbreite (relativ zum Firmennetzwerk) wie DSL bei mir zuhause, auf 200 heruntergeladene Dateien etwa 3 oder 4 Dateien nicht mit übertragen wurden. Um dies zu Verhindern besteht die Möglichkeit nach dem Download die physikalische Existenz der Datei abzufragen um ggf. den Download zu wiederholen:

    void __fastcall DownloadThread::Execute()
    {
            if (!FileExists(strDestPath)) {
                    NMFTP1->Download(strFileName, strDestPath);
            }
    
    //        NMFTP1->Delete(strFileName);
            NMFTP1->Disconnect();
    
            this->ReturnValue = 1;
    }
    

    Für Verbesserungen habe ich natürlich ein offenes Ohr ...

    Gruß MacReeg



  • Als erste Verbesserung würde ich mich von diesen sch...önen TNM* Kompos distanzieren und eher mit Indy liebäugeln 😉


Anmelden zum Antworten