Delphi XE6 paraméteres függvény futtatása külön szálban
2015-06-09T10:57:01+02:00
2015-06-09T23:35:15+02:00
2022-08-18T07:50:33+02:00
Chewy
Sziasztok!

Delphi XE6-ban (firemonkey, de ez jelen esetben mindegy, szerintem) használok egy idTCPServer komponenst, amihez hálózaton keresztül kapcsolódik több kliens.
Az Execute -ban a bejövő kérés alapján mysql adatbázisból kell lekérdeznem adatokat, és azt visszaadni a kliensnek. Ez eltart egy kis ideig. Odáig eljutottam, hogy több szálon kapcsolódok az adatbázishoz, kliensenként. A problémám az, hogy a feldolgozó függvényemnek van egy bemenő paramétere, ami string. Ezt kellene valahogyan külön szálban meghívni, hogy amíg dolgozik rajta, fogadhasson több kérést is. A Feldolgozó függvény használ egyéb függvényeket formázáshoz, de elméletileg thread-safe függvények, nem használnak semmi globális változót. (példában a ProcMSG annyit csinál, hogy a kapott stringet felszabdalja listába egy elválasztó karakter mentén) így próbálkoztam eddig, de nem okés valami... : 

type ThreadIOAnswer = class(TThread) protected procedure Execute; override; public AContext: TIdContext; procedure ThreadIOExec(AContext: TIdContext;); end; procedure ThreadIOAnswer.Execute; begin ThreadIOExec(AContext); end; procedure ThreadIOAnswer.ThreadIOExec(AContext: TIdContext); var a:String; b:TStringList; begin a:=AContext.Connection.IOHandler.ReadLn(); b:=ProcMsg(a); ... Feldolgozás, MySQL kapcsolódás, lekérdezés, eredmény visszaküldés end; procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); var aThread:ThreadIOAnswer; begin aThread := ThreadIOAnswer.Create(True); aThread.AContext := AContext; aThread.Start; aThread.WaitFor; end;

Előre is köszönöm a válaszokat! (bár amikor ezt írom, soha nem jön egy sem, de most bízok Bennetek!

Megelőzve a kérdést, hogy miért nem kapcsolódok a klienssel az adatbázishoz közvetlenül: Azért, mert egy saját tervezésű hardverről van szó, tcp kommunikáció le van programozva benne, de mysql nincs és nem is szeretném.
Mutasd a teljes hozzászólást!

  • Szia!

    Párszor végigolvastam, de még így sem garantálom, hogy jó választ fogok adni, de most már van egy megérzésem... (ha jól értelmeztem a dolgokat)

    Szerintem az a probléma, hogy hiába indítasz külön threadon a feldolgozást a IdTCPServer.Execute-ban... ha ott meg állsz és vársz míg a thread le nem fut.

    El kell indítani a feldolgozást egy threadon (amit persze thread listára kell venni), majd az OnTerminated eseményében (... ha lefutott) kell válaszolni a kliensnek... ha még fel van csatlakozva...

    A lista azért kell, mert ha bezárod a szerver alkalmazást... akkor meg kell várni míg lefutnak...

    A lista countja alapján szabályozhatod, hogy hány szálon fusson a feldolgozás... így a  IdTCPServer.Execute csak annyit adsz vissza válasznak, hogy el lett indítva... vagy el lett utasítva a feldolgozási kérelem.

    BySzi
    Mutasd a teljes hozzászólást!
  • Köszi a választ, jól értelmezed, csak a technikai megvalósításával vannak gondjaim. Tudnál valami példaprogit, mórickaforrást, ami nem száll el?
    Mutasd a teljes hozzászólást!
  • Ha jól tudom a TIdTCPServer minden csatlakozott kliens számára indít egy külön szálat, vagyis az IdTCPServer.OnExecute eljárás mindig az adott kliens szála. Talán nincs is szükség új szálat inditani... csak egy tipp.
    Mutasd a teljes hozzászólást!
  •  valahogyan külön szálban meghívni, hogy amíg dolgozik rajta, fogadhasson több kérést is

    Ha a dokumentáció nem elég világos, akkor célszerű a forrást tanulmányozni! Én ezt tettem... és arra a következtetésre jutottam, amit 3delite is már leírt, vagyis: felesleges új szálakat gyártani, mert az OnExecute kliensenként külön szálban fut (igaz nekem nem XE6-om van, így nem tudok erről helyetted meggyőződni). A kliensek vagy az indítható szálak számát meg lehet határozni, de alap esetben explicit korlátozás nincs. A probléma esetleg a TimeOut-tal lehet talán, ha a munkafolyamat túl hosszúra nyúlik.
    Mutasd a teljes hozzászólást!
abcd