Win7 64bit Delphi7 Thread lefagy, de miért?

Win7 64bit Delphi7 Thread lefagy, de miért?
2015-02-16T16:51:50+01:00
2015-02-22T16:48:27+01:00
2022-10-15T22:26:07+02:00
Kakukk
Sziasztok!
Kis segítség kellene.
A célom hogy egy szál FTP kapcsolatot létesítsen.
Valamit nagyon rosszul csinálok már az elején, mert ezt a kódrészt elindítva 4-5 másodperc múlva lefagy.
Indítani a fő szál formjának FormCreate-ből indítom azonnal :  Feltoltes:=TFeltoltSzal.Create(False);

unit UFeltoltSzal; interface uses Classes, IdFTP, IdComponent, Dialogs, Windows, SysUtils, Graphics; type TFeltoltSzal = class(TThread) private { Private declarations } FTP: TIdFTP; a: Integer; protected procedure Execute; override; public constructor Create(CreateSuspended: Boolean); destructor Destroy; override; end; implementation uses UDM, UFoForm; constructor TFeltoltSzal.Create(CreateSuspended: Boolean); begin inherited Create(True); FTP:= TIdFTP.Create(nil); with FTP do begin Password:=DM.QueryServer.FieldByName('Password').AsString; Host:= DM.QueryServer.FieldByName('Host').AsString; Username:= DM.QueryServer.FieldByName('Username').AsString; Passive:= True; Port:= 21; //OnWork:= FTPWork; //OnConnected:= FTPConnected; //OnDisconnected:= FTPDisconnected; Connect; end; a:= 800; end; destructor TFeltoltSzal.Destroy; begin FTP.Free; inherited; end; procedure TFeltoltSzal.Execute; begin { Place thread code here } Sleep(2000); Windows.Beep(a,500) ; Sleep(2000); end; end.
Execute részbe csak valamit bepötyögtem hogy csináljon valamit.
Ha rossz a kód, akkor kisit részletesebben leírná valaki hogy lenne jó (azt is hogy miért úgy kell ahogy ő ajánlja) azt nagyon megköszönném!
Mutasd a teljes hozzászólást!
Többek között az is okozhatja hogy egy anti-vírus program blokkolja a kapcsolatot vagy a teljes programodat
Mutasd a teljes hozzászólást!

  • Az execute részbe kell a connect, mert így a főszálad bevárja a Create-t.
    Mutasd a teljes hozzászólást!
  • Feltoltes:=TFeltoltSzal.Create(True);
    Feltoltes.FreeOnTerminate:=true;
    Feltoltes.Resume; 
    Ha nem így csinálod az execute végén nem hívódik meg a destructor.

    A Threadod execute részében kellene valami FTP művelet majd egy disconnect, hogy teljes legyen a kód.
    Mutasd a teljes hozzászólást!
  • Ivn.
    Constructorba is lehet csatlakozni, XP-n ez működőképes dolog.
    Arra gondoltam win7 alatt valami más teknika kellene...
    Mutasd a teljes hozzászólást!
  • Javíts ki ha rosszul tudom!
    Feltoltes:=TFeltoltSzal.Create(false); // ezzel azonnal létrehozom de a szál még nem indul el.
    Így csak a szál Constructor része fut le, azaz létrejön.
    Feltoltes.Resume; // ezután lefut az execute rész (dolgozik a szál).
    Feltoltes.FreeOnTerminate:=true; // Ha a szál befejezte a dolgát, felszabadítja saját magát azaz meghívja saját destruktorát.
    Ha van általam készített destuktor, akkor őt hívja meg.

    Valamit rosszul tudok ?
    Mutasd a teljes hozzászólást!
  • Nem látom sehol a kódodban hogy elindítanád a szálat suspended módban van a konstruktorban létrehozva és sehol egy resume.
    Mutasd a teljes hozzászólást!
  • Feltoltes:=TFeltoltSzal.Create(false);
    Feltoltes.Resume;
    Ez a FőForm CreateForm eseményében van.
    Program indulásával a szálat is indítani szeretném.
    Amivel nemvagyok tisztába az a feljebb leírtak.
    Abban még nem erősített meg senki hogy jól, vagy esetleg rosszul tudnám.
    Feltoltes:=TFeltoltSzal.Create(false);
    Feltoltes:=TFeltoltSzal.Create(True);
    Ezt a két dolgot keverem lehet !
    Mutasd a teljes hozzászólást!
  • Ok már észrevettem csak már alig látok mert 2 napja fent vagyok. Az inherited Create(True);
    után mindenképpen kell egy freeonterminate:=true; sor mert a főszálból nem fogod tudni, hogy mikor lehet felszabadítani.Valami az FTP kapcsolódással lehet probléma nálad. mert connect nélkül simán lefut a szál és beep után kilép. Mivel a konstruktor neve és paraméterezése ugyazaz mint az ősé legalább egy overload kellene mögé. Ami probléma még lehet, ha exception lép fel a kapcsolódásnál. Ha ez a főszálban történne akkor feldobna egy szép piros ikonos ablakot de szálban lehet hogy csak elhal. Tegyél a connect köré egy try except end;  blokkot és a letölténél sem ártana egyrész ellenörizni hogy connected e a státusza a komponensnek, másrészt még így is try except end;
    közé kéne tenni a letöltést és esetleges hibál kiírathatnád logfájlba az ötösért 
    Mutasd a teljes hozzászólást!
  • Feltoltes:=TFeltoltSzal.Create(True);
    Feltoltes.FreeOnTerminate:=true;
    Feltoltes.Resume;

    Ezt írtad először.
    Ezesetben is kellene az inherited Create(True); után egy freeonterminate:=true; sor ?
    Úgy gondolom ezesetben nem kell, hisz indítás előtt ezt megmondom neki.

    Ami még fontos, 32bit XP stabil !
    Win7 64bit még mindíg fagy, csak az intézővel tudom kilőni a progit.
    Mutasd a teljes hozzászólást!
  • try except ? Logolás? Már csak azért is mert tűzfaltól a víruskeresőig bármi blokkolhatja , így ha jó a login akkor sem biztos hogy létrejön a kapcsolat. Tehát ki kéne íratni az esetleges hibaüzenetet fájlba.
    Mutasd a teljes hozzászólást!
  • Igazából az is csúnya dolog hogy a datamodult közvetlen a szálból nyüstölöd. Azt legfeljebb egy szinkronizált metódusból szabadna. Valamikor én írtam ide a ezt a feltöltéses kódot és pont azért csináltam olyan konstruktort hozzá amiben plusz paraméterek vannak, hogy a főszál kérje le az adatokat (usernév, host, jelszó) és ezeket a konstruktornak paraméterként adja át ami szépen beállítja a privát változókat illetve az ftp komponens mezőit. Az a csoda , hogy így futott neked XP-n  
    Mutasd a teljes hozzászólást!
  • Lehet h kevered is, de rosszul is csinálod :)

    Ezzel ugye eddig elvileg nincs baj:

    constructor TFeltoltSzal.Create(CreateSuspended: Boolean);

    Meghívod így:

    TFeltoltSzal.Create(True);

    A paraméter neve: "CreateSuspended"
    true esetén várja, hogy hívj a száladra egy ".Start"/".Resume" -t, különben suspendben áll és vár.
    false esetén nem vár senkire elindul a szál.

    De:

    inherited Create(True);
    Az ős konstruktort (leszarva a paramétert) fixen suspendelve hívod.

    Így az történik amit te akarsz:

    inherited Create(CreateSuspended);

    De2:
    Ivn korábban leírta, az Execute-ba kell a Connect!
    Ha a Connect szinkron hívás akkor addig nem tud továbblépni a program amíg be nem fejeződik, mivel a konstruktor a főszál kontextusában fut.
    Mutasd a teljes hozzászólást!
  • Execute részbe csak valamit bepötyögtem hogy csináljon valamit.

    Ha lefagy valahol akkor az nem a konstruktorban történik hanem pont az execute részben amit nem írtál be, mivel a konstruktor még a főszálban fut. Az a gyanúm hogy az execute részben közvetlen piszkálod a datamodult és/vagy a vizuális komponenseket a synchronize használatának mellőzésével
    (valahol meg kell adni az FTP nek hogy miket töltsön le  ) , vagy az FTP komponens eseménykezelőit kötöd közvetlen a felülethez hogy megjelenítsd a működését. A kód általad beírt részében nincs hiba azt leszámítva, hogy az ftp connectjét célszerű lenne az execute elejére tenni, a hiba abban a részben van amit nem akartál nyilvánosságra hozni.
    Mutasd a teljes hozzászólást!
  • Sziasztok!
    Elnézést a hosszú szünetért, belefutottam egy randa megfázásba.
    Amiér értetlenkedem annak oka, hogy gyenge amatőr próbálgatás amit csinálok, sosem tanultam programozni, csupán csak érdekel hobbi szinten.
    Viszont örülök minden hozzászólásnak, merthogy megint okosodtam általatok!
    Szóval amiket mondtatok, én azokat összerakva javítom a kódot, és bemásolom majd ide.
    Ti szakértői szemmel nézitek, előre is elnézést a bénázásér.
    A construktor rész homályos még nekem, illetve ez az öröklődéses dolog...
    utánna olvasok!
    Addig is köszönöm a segítségetek.
    Mutasd a teljes hozzászólást!
  • procedure TFoForm.SzalinditasTimer(Sender: TObject); var Password, Host, User: string; begin Szalinditas.Enabled:= False; Password:= DM.QueryServer.FieldByName('Password').AsString; Host:= DM.QueryServer.FieldByName('Host').AsString; User:= DM.QueryServer.FieldByName('Username').AsString; (******************************************************************************) (* Szál indítása *) (******************************************************************************) Feltoltes:=TFeltoltSzal.Create(True, Password, Host, User); Feltoltes.FreeOnTerminate:= True; // Letoltes.Priority:= tpHighest; Feltoltes.Resume; end;
    Timerrel indítom a szálat.

    Maga a szál: 

    unit UFeltoltSzal; interface uses Classes, IdFTP, IdComponent, Dialogs, Windows, SysUtils, Graphics, Forms; type TFeltoltSzal = class(TThread) private { Private declarations } FTP: TIdFTP; protected procedure Execute; override; procedure FTPConnected(Sender: TObject); procedure FTPDisconnected(Sender: TObject); procedure Rajz; public constructor Create(CreateSuspended: Boolean; P,H,U: String); overload; destructor Destroy; override; end; implementation uses UDM, UFoForm; constructor TFeltoltSzal.Create(CreateSuspended: Boolean; P,H,U: String); begin inherited Create(Createsuspended); FTP:= TIdFTP.Create(nil); with FTP do begin Password:= P;//DM.QueryServer.FieldByName('Password').AsString; Host:= H;//DM.QueryServer.FieldByName('Host').AsString; Username:= U;//DM.QueryServer.FieldByName('Username').AsString; Passive:= True; Port:= 21; OnConnected:= FTPConnected; OnDisconnected:= FTPDisconnected; end; end; destructor TFeltoltSzal.Destroy; begin FTP.Disconnect; FTP.Free; inherited; end; procedure TFeltoltSzal.Execute; begin { Place thread code here } try FTP.Connect; except on E : Exception do begin ShowMessage('Exception class name = '+E.ClassName); ShowMessage('Exception message = '+E.Message); end; end; Windows.Beep(1000,500) ; Sleep(1000); Windows.Beep(800,500) ; end; procedure TFeltoltSzal.FTPConnected(Sender: TObject); begin Synchronize(Rajz); end; procedure TFeltoltSzal.FTPDisconnected(Sender: TObject); begin Synchronize(Rajz); end; procedure TFeltoltSzal.Rajz; begin if FTP.Connected then FoForm.Shape1.Brush.Color:= clLime else FoForm.Shape1.Brush.Color:= clRed; end; end.
    XP-n megy most, és  itt stabil.
    Próbáltam mindenki javaslatát belevinni a kódba, remélem sikerült.
    Persze korántsincs kész ezt látjátok.
    Valóban ha kivettem a connectet akkor nem fagyott!
    Win 7-en még próbálom majd.
    Mutasd a teljes hozzászólást!
  • Sziasztok!
    Vakvágányra futottam, teljes a tanácstalanság...
    Win7 64bit környezetben a következő van:
    Egyszálasra kijavítva a program mindíg fagy.
    A fagyást úgy kell érteni, hogy a keretprogram teljesen jól működik (legalábbis látszólag azt csinálja amit kell).
     De amint a formra dobok egy IdFTP kompit, beállítom közvetlenül a kapcsolathoz szükséges  propertiket (user, host, password, a többi alapon van) és buttonra connect, akkor a form kapcsolódás után lemerevedik, a delphi menüi csak elszineződnek ha valamire egérrel ráállok, de nem reagálnak semmire.  Akkor jön vissza a delphi működőképessége ha az intézőt elindítom.
    Programot, folyamatot  sem kell bezárnom, elég ha az intézőt megnyitom és utánna közvetlenül be is zárhatom.
    Ekkor a delphi menürendszere megjavul és ki reszetelhetem a programom.
    Illetve intézővel kilőhetem a programom és minden rendben lesz utánna.
    A connect try except end között van, e.message semmit nem ír ki ...
    Ez a jelenség van akkor is, ha NMFTP-t használok.
    Ez a jelenség  csatlakozáskor és csatlakozás után következik be, azaz valamikor elfut a program 15-20 m.percet is.
    A furcsaság:
    sima formra ugyanezt a kapcsolatot létrehozom, akkor simán fut fagyás nélkül minden!
    Arra következtetek, (nembiztos hogy jól) hogy valamit mégiscsak a keretprogramba szúrok el.
    Az egész kódot csak utolsóként másolnám be, mert nem két sor.
    Viszont Ado kapcsolatokat bűvölök data modulról doConnection, AdoQuery,  DataSource keresztül teljesen szokványos módon.
    Mi okozhat ilyen jelenséget ?
    Valózínű ez a topic aktualítását fogja veszíteni mert már nem a címben foglalt lesz a hiba.
    Ötletek ?
    Mutasd a teljes hozzászólást!
  • Többek között az is okozhatja hogy egy anti-vírus program blokkolja a kapcsolatot vagy a teljes programodat
    Mutasd a teljes hozzászólást!
  • Volt már olyan, de akkor feltette a kérdést h. mit tegyen.
    Kivételek közé tettem és ment rendesen.
    Esetleg az okozhatja hogy a kapcsolatom roouteren kereszült megy és annak a tűzfala blokkolja a portot ?
    Roouter beállításokhoz nemnagyon konyítok, de utánna járok.
    Viszont amit írtam h. a keretprogim nélkül egy teljesen új applikációval felépített ugyanolyan kapcsolat meg hiba nélkül fut.
    Ezesetben is blokkolnia kéne annak a dolognak a kapcsolatot nem ?
    Már arra is gondoltam h. valahogy sérült az oprendszerem, de azon sem tapasztalok semmi rendellenességet, ráadásul csomó mindent kéne visszarakni ha újra telepíteném.
    Arról meg nemis beszélek h. a guta ütne meg ha utánna is rossz maradna a progi :D
    Mutasd a teljes hozzászólást!
  • Miután a szálon belül van a connect  így az aligha okozhatja a fagyást, valami más kell legyen a baj.
    Viszont az except részben a ShowMessage nem túl szerencsés, inkább így:

    ... on E : Exception do begin FErrorMessage := e.message; // FErrorMessage az osztály belső string változója Synchronize(ShowError); end; ... procedure ShowError(); begin ShowMessage(FErrorMessage); end;

    A fagyást úgy kell érteni, hogy a keretprogram teljesen jól működik
    De amint a formra dobok egy IdFTP kompit

    Ezt hogy kell érteni?
    Mutasd a teljes hozzászólást!
  • Jó lenne, ha az összes kódrészt ami eléri és használja az  FTP kompit bemásolnád, úgy, hogy lássuk melyik szálból, hogyan használod +
    "Egyszálasra kijavítva a program mindíg fagy."
    Mi az, h egyszálasra kijavítva?
    Mutasd a teljes hozzászólást!
  • A router nem lehet az oka mert azt írod hogy egy üres formról gyorsan tudsz kapcsolódni, csak a meglévő alkalmazásodban hal el.
    Mutasd a teljes hozzászólást!
  • Egyszálasra kijavítva azt értem h. csak a főszál van, nincs semmi TThread-ba.
    Holnap jutok ahoz a géphez ahol a fejlesztés van, bemásolom az egész kódot + adatbázist.
    Az általatok javasoltak alapján javítottam a TThread-os változatot is, és XP-n stabilan működik mindkét változat.
    Esetleg lehet olyan telepített kompi amit használok és win7-nek nemtetszik ...
    Bár ez csak egy button kompi ... hát nemtom ...
    XP amúgy 32 bites amin stabil.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd