Aszinkron adat töltéssel ado Delphi

Bizonyos esetekben meg kell tennünk aszinkron betöltését az adatokat az adatbázisból. Végtére is, így a felhasználó szinte azonnal látni az első darab adatokat, amint azok letöltődnek, ahelyett, hogy megvárná, amíg minden be van töltve teljesen. Több felhasználó képes lesz, hogy megszünteti a letöltési bármikor amíg meg nem történik. És persze, az aszinkron betöltés lehetővé teszi, hogy például mnogozakladochny felhasználói felület, az egyes lapokat, amelyek párhuzamos lesz betölteni a különböző adatokat. Ebben a cikkben nyújt megoldást, hogy majd aszinkron körökre terhelési adatokat egy táblázat segítségével Delphi ADO.

Projekt létrehozása

Tény, hogy az ADO minden készen áll az aszinkron betöltését adatokat, akkor kell csak beállítani bizonyos opciók és a szükséges eljárás eseményeket. De Delphi mindent nem volt olyan egyszerű. Hogy az adatok megjelenítésére a táblázatot használjuk TDBGrid Delphi örökölt TCustomDBGrid (vagy több harmadik fél fejlesztési, szintén örökölt TCustomDBGrid), utalva az objektum TDataSource, amely viszont, utal, hogy a TDataSet. És ha dolgozik, ADO, akkor kell használni egy átalakító TADOStoredProc, TADOQuery, TADOTable és TADODataSet, amelyeket örökölt TDataSet objektumot. Csak a csomagolás, és nem ad teljes erővel az aszinkron betöltését adatokat. Ahhoz, hogy megértsük, mi működik és mi nem működik, ha ezekkel a csomagolást, hogy egy egyszerű példát használja őket.

Most a Delphi, hogy egy új projekt a VCL-forma (Fájl menü -> New -> VCL Forms Application - Delphi), a táblázat formájában meghatározott TDBGrid és két TButton a gombot. Az egyik gomb a letöltés megkezdéséhez, és a második, hogy megszünteti a letöltést. Adom a nevét a gombok megfelelő - ButtonLoad és ButtonCancel. Az összes egyéb változatlan marad. Gomb alapértelmezés lemondás esetén inaktív, Enabled kitenni False. Mi határozza meg azt is, képezi a cím és a szöveg a gombok. Majd még több TProgressBar komponens, amely megmutatja nekünk, hogy a boot folyamat megy, vagy nem, és TLabel alkatrész megjelenítéséhez rekordok száma betöltve. Stílus tulajdonsága állapotjelző ki pbstMarquee, és látható - False.

Miután a vizuális része a formanyomtatvány, tegye a forma TDataSource alkatrészek és TADOQuery TADOConnection. Most meg kell társítani TDBGrid asztal (mi megkapta DBGrid1 név) a TDataSource adatforrás (esetünkben nevezték DataSource1), adatforrás - kérés TADOQuery (mi ez elemzi ADOQuery1), és a kérés - a TADOConnection kapcsolat (mi azt elemzi ADOConnection1). Ie kiderül, hogy egy ilyen kapcsolat: DBGrid1 -> DataSource1 -> ADOQuery1 -> ADOConnection1. Erre sor y táblázat DataSource tulajdonságát DataSource1, adatforrás tulajdonságainak DataSet egyenlő ADOQuery1, kapcsolódási kérést ingatlan ADOConnection1.

Aszinkron adat töltéssel ado Delphi

Most be kell állítania a csatlakozási tulajdonságokat az ingatlan ConnectionString ADOConnection1 objektumot. Azt fogja követni ezt a sort:

Itt én csak egy felhasználónévvel és jelszóval, így ki lehet kapcsolni az alapértelmezett felhasználói név és jelszó kérése ablaknak ingatlan LoginPrompt ADOConnection1 komponens False.

Most jön az ilyen kérelmet, amelyet végre hosszú ideig, és írd meg az SQL ADOQuery1 alkatrész tulajdonság. Ugyanakkor mi lesz pontosan mennyit fog betölteni az adatokat az egyes opciók közül választhat. Csináltam egy ilyen kérés itt:

Én ezt a lekérdezést SQL Management Stodio fejezni 1 perc 9 másodperc.

Egyszerű szinkron lekérdezését Delphi segítségével ADO

Kezdeni, hogy egy egyszerű szinkron kérés. Teljesíti a kérést esemény OnClick ButtonLoad gombra. Hogy ilyen van a kód a lekérdezés:

Aszinkron adat töltéssel ado Delphi

Egyszerű aszinkron adat kérés Delphi segítségével ADO

Most megpróbáljuk teljesíteni ezt a kérést aszinkron. Ehhez a tulajdonságait az alkatrész ExecuteOptions ADOQuery1 eoAcyncExecute doboz True. A kapcsolat a DBMS is előfordulhat aszinkron beállítani az ingatlan értékét ConnecOptions coAsyncConnect. Most a bejegyzések száma kell, hogy csak a kérés elküldése után kivégezték. Ez megtalálható az esemény AfterOpen ADOQuery1 komponenst. Hibák lehet fogni az esemény OnExecuteComplete ADOConnection1 komponenst. Mindaddig, amíg a kérelem feldolgozása, megmutatjuk a folyamatjelző sáv, így aktív „Mégse” gombra, majd a gomb „Download” - inaktív. Megszakítása futó lekérdezés lesz, mint amilyennek lennie kellene ADO - hívja a Cancel funkció. Íme a kód nézne:

Aszinkron adat töltéssel ado Delphi

Törlése egyszerű aszinkron adatkérést a Delphi segítségével ADO

Töltse le a fenti példa jól működik, amíg nem kattint a „Mégsem” gombra. Vannak 2 probléma:

    1. Ha az adatok már elkezdték betölteni az ügyfél, a lemondás nem működik. Ahelyett, hogy törli a program lefagy a sorban «ADOQuery1.Recordset.Cancel;», amíg az összes adat már a teljes terhelést.
    2. Miután felhívta «ADOQuery1.Recordset.Cancel;» funkció (kivéve, ha a tényleges kérelmet törölték, ld. 1.), Re-a megkeresés nem sikerül, mivel metódushívás «ADOQuery1.Open;» nem fog nincs hatása. Ez annak a ténynek köszönhető, hogy a ADOQuery1 alkatrész zárva marad (Active = False), de ugyanakkor, az állapota azt jelzi, hogy a lekérdezés megnyitásakor (State = dsOpening). Ez világosan mutatja, hogy a burkolat a ADO VCL nem támogatja hatályon kívül helyezésére.

akkor meg kell kérni körül az első probléma a következő három módon:

    1. Változás vezetőt, ha egy másik vezető van. De előfordulhat, hogy a meghajtó szükséges nem létezik, vagy az adatbázis nem támogatja a megszüntetése a kéréseket.
    2. Használjon egy szerver oldali kurzor (ehhez meg kell tenni egy komponens ADOQuery1 CursorLocation ingatlan clUseServer). De a szerver oldali kurzort, nem lehet tudni, a rekordok száma és az adatok megjelenítéséhez szükség van egy állandó kapcsolatot az adatbázissal. Ezért dolgozni az adatokat a kliens, akkor másolja őket a memóriában (pl a TClientDataSet), vagy a helyi adatbázisban, ha az adatok mennyisége igen nagy. A olvasata az összes adatot a szerver kurzor lassú.
    3. Készíts egy dummy terhelés megállítani. Ie azt mutatják, hogy a felhasználó vonja vissza a kérést, és valóban ad, hogy végre a végére, és csak ezután eltávolítani. Akkor biztosan törölni alkatrészek TADOQuery bootoláskor (ez lehetséges, ha True eoAsyncFetchNonBlocking zászló), de az adatok letöltése ADO objektumok ugyanakkor nem áll meg, hogy továbbra is. Ez nyilvánvaló, még a Task Manager. Ezen felül, ha eltávolít TADOQuery alkatrészek boot során időszakosan nem «access violation at 0x1cbaf811: olvasni a címet 0x00000000» valahol a gyomrában a ADO.

A második problémát nem lehet megkerülni. Csak egy megoldás - miután minden lemondás (vagy akár minden egyes alkalommal) minden új kérelmet, hogy hozzon létre egy új komponenst TADOQuery, és a meglévő komponenseket eltávolítjuk azonnal vagy később, amikor az alkalmazás leáll.

Figyelembe véve eredő lemondás a probléma, alakja kódot sokat változott. Leveszem a penész alkatrészek és ADOQuery1 ADOConnection1 és építem őket minden alkalommal, amikor betölteni az adatokat. Az alábbiakban adok két példát ismertetjük és hátrányai.

Itt az első példa. Itt használjuk a szerver oldali kurzort az adatok lekéréséhez. Megmutatni azt másolja az adatokat a TClientDataSet. Mégsem letöltés itt tökéletesen működik. De vannak más kérdés, hogy lesz írva az alábbiakban.

Aszinkron adat töltéssel ado Delphi

Tehát, ha azt szeretnénk betölteni a felhasználó számítógépén egy nagy mennyiségű adatot, meg kell találni egy másik utat. A fenti példa a rakodási és tárolási adatok a memóriában alkalmas csak a kis térfogatú.

Aszinkron lépésenként adatok betöltését Delphi segítségével ADO

A jelentését növekvő terhelési hogy a felhasználónak nem kell várni, amíg a végén a lekérdezés, hogy az adatokat. Miután az első adat van betöltve, akkor már lehet, hogy megjelenítse a táblázatban. Ezt követően, ahogy podgruzki egyre több új adatot ők is megjelennek a táblázatban. Így a felhasználó azonnali megtekintéséhez az asztalon szinte azonnal a letöltés elkezdése után, és látni fogja a dinamika a terhelést.

Két lehetőség van, hogyan kell csinálni. Az első lehetőség - ez a kis változás az előző példában, amikor a terhelés zajlik szerver oldali kurzort. Hogy mit jelent a változás, hogy mi azonnal kötődnek a tábla komponens TClientDataSet és a TClientDataSet töltés, az asztal azonnal megjelenik az új rekordot. Lesz csere csak a módszerek és AfterOpen WndMethod:

A második lehetőség -, hogy telepítse eoAsyncFetchNonBlocking zászlót True TADOQuery alkatrész és fokozatos adatok betöltését OnFetchProgress esemény. Ez a módszer működik 10-szer gyorsabb, mint az előző. Azonban itt én került szembe egy másik probléma: ha egy minta esetén OnFetchProgress adatokat nem lehet beállítani a kurzort az első bejegyzés (vagy metódushívások első előzetes nem segített), és ennek eredményeként, mi fog letölteni az összes rekordot az első kivételével. Ennek elkerülése érdekében, akkor töltse le az adatokat közvetlenül ADO. Egy példa változik sokat, úgyhogy itt megemlíteni a teljes szöveg:

Aszinkron lépésenként betöltés több adathalmazok Delphi segítségével ADO

Ha kell aszinkron feltölteni több adathalmaz, valamint az előző példában, ha nem is próbálja csinálni. A tény az, hogy ha lépni a következő adathalmaz segítségével «query.Recordset: = query.NextRecordset (recordsAffected)», ebben a pillanatban TADOQuery alkatrész lezárja a kurzort, és többet kap semmit. Igen, ez kiválóan működik szinkron kéréseket, de nem egy esemény OnFetchProgress. Példa az olvasás a szerver kurzor sem fog működni.

Kapcsolódó cikkek