[delphi] thread die events van component opvangt en verwerkt

Pagina: 1
Acties:

Anoniem: 116711

Topicstarter
Hoi,

ik ben hier bezig met een applicatie die moet reageren op veranderingen in een nie lolale database. Dit proces wil ik op de achtergrond laten gebeuren zodat de user gewoon door kan werken.
ik ben hiervoor een thread aant bouwen die een component bezit die events uitspuugd als er iets veranderd in de database.
het probleem is dat deze events niet opgevangen worden als ik dit in een thread doe, doe ik het in het hoofdprogramma werkt dit wel goed.
de bedoeling is dat de thread gewoon blijft draaien en alleen wat operaties uitvoerd zodra hij zo'n event geeft.
ik zal hier ff de code van de thread Execute zetten:

code:
1
2
3
4
5
6
7
8
9
10
11
12
procedure EventHandler.Execute;
var nDbListener: TPSQLNotify;
begin
  SetName;
  { Place thread code here }
  nDbListener := TPSQLNotify.Create(nil);
  nDbListener.Database := dmMain.dbTest;
  nDbListener.ListenList.Add('user_login');
  nDbListener.OnNotify := nListenerNotify;
  nDbListener.Active := true;
  WaitFor
end;


of dat WaitFor het juiste commando is vraag ik me af.
ik heb een breakpoint gezet bij de code van nListenerNotify maar daar wil hij niet stoppen terwijl hij dat wel zou moeten doen.
merkwaardig is dat als ik daar in een loopje enkele MessageDlgs laat langskomen en ik laat tussen 2 Dlgs door iets veranderen in de db dat hij dan wel stopt bij die event.
heb ook al geprobeerd met een lege loop maar ook dat wil hij niet vreten.

iemand een idee hoe dit moet?

Anoniem: 113889

Wat informatie uit de Delphi help:

Bij Threads:
Most methods that access an object and update a form must only be called from within the main thread or use a synchronization object such as TMultiReadExclusiveWriteSynchronizer.

Bij TThread.Waitfor:
Do not use the properties and methods of other objects directly in the Execute method of a thread. Instead, separate the use of other objects into a separate procedure call, and call that procedure by passing it as a parameter to the Synchronize method.

Execute voor een Delphi-TThread is de levensloop van het ding. Waitfor wacht tot de thread doodgaat (einde execute). Door Waitfor in Execute plaatsen dead-lock je de thread: hij blijft checken oftie dood is :) .

Delphi threads zijn erg picky met gebruik van objecten uit andere threads en in het bijzonder met objecten van TComponent of hoger. Alle toegang moet gesynchroniseerd worden. In de help van Delphi staat hoe dit gedaan kan worden. Er is ook een threads-voorbeeld dat ik indertijd erg verhelderend vond.

Anoniem: 116711

Topicstarter
Delphi threads zijn erg picky met gebruik van objecten uit andere threads en in het bijzonder met objecten van TComponent of hoger. Alle toegang moet gesynchroniseerd worden.
Dit component (TPSQLNotify) zit toch in deze thread? Hoeft toch niet gesynchroniseerd worden dan ofwel?
Execute voor een Delphi-TThread is de levensloop van het ding. Waitfor wacht tot de thread doodgaat (einde execute). Door Waitfor in Execute plaatsen dead-lock je de thread: hij blijft checken oftie dood is.
da's duidelijk, maarreh kan iemand me vertellen hoe ik deze thread oneindig (ofja eigenlijk zolang nDbListener.Active) kan laten draaien?
en een verklaring waarom hij met een lege loop niet in die nListenerNotify procedure terecht komt en als ik wat nutteloze dingen op het scherm laat zien in een loopje en ik tussentijds iets wijzig in de db (wijzigen in de db triggert dat event) hij dat wel doet?!

alvast bedankt voor reply!

Anoniem: 116711

Topicstarter
okee, heb het iets anders aangepakt nu:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure EventHandler.Execute;
begin
  SetName;
  { Place thread code here }
  Synchronize(InitListener);
  repeat
  until false
end;

procedure EventHandler.InitListener;
begin
  nDbListener := TPSQLNotify.Create(nil);
  nDbListener.Database := dmMain.dbEhotel;
  nDbListener.ListenList.Add('hotel_login');
  nDbListener.OnNotify := nEhotelListenerNotify;
  nDbListener.Active := true;
end;


dat werkt idd een stuk beter! :)

nu is alleen nog de vraag hoe ik die thread oneindig laat draaien? kan dat met een lege lus, of is hier een mooiere oplossing voor?

  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
Nu doet je thread niets anders dan wachten tot hij afgeschoten wordt... Als je thread een object herbergt, dan kun je dit als eigenschap van je thread class toevoegen.
Je start je thread dan altij in Suspended mode en Resume'd zodra je initialisatie klaar is.

De main loop van je thread (Thread.Execute) zou er eigenlijk als volgt moeten uitzien:

code:
1
2
3
4
5
6
7
procedure TMyThread.Execute;
begin
  while not Terminated do
  begin
    // Doe je ding...
  end;
end;


Nu kun je vanuit je hoofdthread de thread Terminaten en dan een WaitFor aanroepen om te wachten tot je thread klaar is.

Anoniem: 113889

Anoniem: 116711 schreef op 29 september 2004 @ 14:27:
[...]Dit component (TPSQLNotify) zit toch in deze thread? Hoeft toch niet gesynchroniseerd worden dan ofwel?
[...]
Heb ik niet goed uitgelegd.

Delphi is heel goed in het maskeren de basale Windows-events: Window-Messages. Zodoende hoeven Delphi-programmeurs geen Message- en Window-procedure te schrijven. Nadeel is echter dat dit met multi-threading niet altijd even handig uitpakt. Threads hebben namelijk een eigen message loop en die is niet zo 1 2 3 fine te tunen is. IPV de message loop-procedure biedt Delphi TThread::Execute.

VCL-klasses zijn zo gebouwd dat ze altijd via de main thread aangestuurd worden. Dit kan via een procedure op de main thread of via TThread.Synchronise dat stiekum via de mainthread loopt. Een eigen van TObject afgeleide klasse doet het meestal nog wel met directe aansturing, vanaf TComponent werkt het niet meer.
Dat een TComponent door de thread geownd wordt, doet er niet meer toe.

De code van Robbemans is de basic Delphi thread lus. Binnen deze lus moet je condities controleren en steeds een Synchronize(Actie) ondernemen. ZUlke code lijkt betrekkelijk stom maar het is de manier waarop heel Windows werkt: messageloopjes die wachten tot er wat interessants gebeurt.

Anoniem: 116711

Topicstarter
goed heb het allemaal aant werken nu,
2 problemen:

- het programma hapert als de tering! als ik met de form over mijn desktop heensleep gaat dit echt verschrikkelijk traag.
- de main form hapert nog steeds, terwijl deze alleen af en toe een tesktje in een memo moet plakken, de rest (ook de queries) zouden door de thread moeten gebeuren nu.

zal ff het programma nog iets verduidelijken wat hij zou moeten doen.
- de db spuugt een event uit (dmv rules) als er een user inlogd.
- de thread vangt deze op
- de thread zoekt de laatst ingelogde user op in een tabel en hierbij de bijbehorende username (zit in 1 query met een join)
- de thread geeft een string door naar de main form die deze in een memo zet.

dan hier ff de ge-update code van de thread:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure EventHandler.Execute;
begin
  SetName;
  { Place thread code here }
  Synchronize(InitListener);
  Synchronize(InitQuery);
  while not Terminated do
    if Length(fEventQueue) > 0 then
    begin
      if fEventQueue[0] = EV_USER_LOGIN then
        Synchronize(UpdateMemo);
      if Length(fEventQueue) > 1 then
        fEventQueue := Copy(fEventQueue, 1, Length(fEventQueue) - 1)
      else if Length(fEventQueue) = 1 then
        fEventQueue := 0;
    end
end;


deze werkt dus een array van events af die hij moet verwerken.

update memo doet een query en stuurt het resultaat hiervan in een string door naar een procedure in de mainform die deze in een memo zet.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:12

Creepy

Tactical Espionage Splatterer

Zet in de loop van je trhead eens een sleep(10) o.i.d. Nu geeft je thread nooit CPU tijd vrij voor gebruik van andere threads / processen

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Anoniem: 116711

Topicstarter
hmm,
heb wat gespreeld met die sleep maar het hoofdprogramma lijkt nog steeds te moeten wachten zodra de thread bezig is een query uit te voeren. ook als ik hem best lang (500ms bijv.) laat 'slapen'.

je zou toch zeggen dat wanneer een thread die deze zaken ophaald het hoofdprogramma eigenlijk nooit hierop zou moeten wachten?

ik zal nog eens wat code posten van hoe dit event verder wordt doorgegeven aan de mainform, misschien dat ik daar ergens iets fout heb gedaan?

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure EventHandler.UpdateMemo;
var query, naam, timestamp: string;
begin
  query := 'SELECT "User_login_log".user_id , login_tc, name ' +
           'FROM "User_login_log" ' +
           'LEFT JOIN "Users" ON "Users".user_id = "User_login_log".user_id ' +
           'WHERE login_tc = ' +
           '(SELECT MAX(login_tc) ' +
           'FROM "User_login_log")';

  fQuery.SQL.Add(query);
  fQuery.Open;
  naam := fQuery.FieldByName('user_id').AsString;
  timestamp := fQuery.FieldByName('login_tc').AsString;
  fQuery.Close;
  fmMain.mEventLog.Lines.Add('user ingelogd ' + naam + ' ' + timestamp);
end;


ps: de query zit in de thread maar deze wordt gedaan op een database die in het hoofdprogramma op een datamodule staat. kan dit hier iets mee te maken hebben?

  • cimbom
  • Registratie: Juni 2001
  • Laatst online: 26-04-2024

cimbom

Just Kidding

Je zegt toch Synchronize(UpdateMemo) dus die query wordt uitgevoerd door mainthread.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:12

Creepy

Tactical Espionage Splatterer

Alles wat je in je thread uitvoert loop parallel aan de rest van je programma. Tenzij (!) je synchronize gebruikt. Dan wordt de code door je hoofdprogramma uitgevoerd.

Zorg dus dat je in je thread zoveel mogelijk in je code de gebruikte objecten aanmaakt, en geen gebruik maakt van visuele componenten of componenten die al ergens op een form staan. Synchronize heb je alleen nodig om vanuit je thread visuele dingen aan te spreken of om dingen aan te spreken die op datzelfde moment ook door een ander stuk code (hoofdprogramma, andere thread) uitgevoerd kunnen worden.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • cimbom
  • Registratie: Juni 2001
  • Laatst online: 26-04-2024

cimbom

Just Kidding

Anoniem: 116711 schreef op 30 september 2004 @ 11:24:
hmm,
heb wat gespreeld met die sleep maar het hoofdprogramma lijkt nog steeds te moeten wachten zodra de thread bezig is een query uit te voeren. ook als ik hem best lang (500ms bijv.) laat 'slapen'.

je zou toch zeggen dat wanneer een thread die deze zaken ophaald het hoofdprogramma eigenlijk nooit hierop zou moeten wachten?

ik zal nog eens wat code posten van hoe dit event verder wordt doorgegeven aan de mainform, misschien dat ik daar ergens iets fout heb gedaan?

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure EventHandler.UpdateMemo;
var query, naam, timestamp: string;
begin
  query := 'SELECT "User_login_log".user_id , login_tc, name ' +
           'FROM "User_login_log" ' +
           'LEFT JOIN "Users" ON "Users".user_id = "User_login_log".user_id ' +
           'WHERE login_tc = ' +
           '(SELECT MAX(login_tc) ' +
           'FROM "User_login_log")';

  fQuery.SQL.Add(query);
  fQuery.Open;
  naam := fQuery.FieldByName('user_id').AsString;
  timestamp := fQuery.FieldByName('login_tc').AsString;
  fQuery.Close;
  fmMain.mEventLog.Lines.Add('user ingelogd ' + naam + ' ' + timestamp);
end;


ps: de query zit in de thread maar deze wordt gedaan op een database die in het hoofdprogramma op een datamodule staat. kan dit hier iets mee te maken hebben?
OK, ik zou een aparte procedure maken inthread GetUserName ofzo die de query uitvoerd.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure EventHandler.GetUserName ;
var query: string;
begin
  query := 'SELECT "User_login_log".user_id , login_tc, name ' +
           'FROM "User_login_log" ' +
           'LEFT JOIN "Users" ON "Users".user_id = "User_login_log".user_id ' +
           'WHERE login_tc = ' +
           '(SELECT MAX(login_tc) ' +
           'FROM "User_login_log")';

  fQuery.SQL.Add(query);
  fQuery.Open;
  naam := fQuery.FieldByName('user_id').AsString;
  timestamp := fQuery.FieldByName('login_tc').AsString;
  fQuery.Close;
  
end;


en deze roep je in Execute zonder Synchronize.
daarna roep je volgende met synchronize
code:
1
2
3
4
procedure EventHandler.UpdateMemo;
begin
  fmMain.mEventLog.Lines.Add('user ingelogd ' + naam + ' ' + timestamp);
end;


Naam en timestamp als private variabelen van thread declareren


wijziging:
regel
fmMain.mEventLog.Lines.Add('user ingelogd ' + naam + ' ' + timestamp);
moest weg uit getusername

[ Voor 13% gewijzigd door cimbom op 30-09-2004 11:38 ]


  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
Anoniem: 116711 schreef op 30 september 2004 @ 11:24:...

ps: de query zit in de thread maar deze wordt gedaan op een database die in het hoofdprogramma op een datamodule staat. kan dit hier iets mee te maken hebben?
AUW! Houdt dit in je achterhoofd:

ELKE THREAD MOET EEN EIGEN CONNECTIE HEBBEN NAAR JE DATABASE!

Ja, dit moet ff in hoofdletters. Dit is om te voorkomen dat er meerdere actieve queries komen op een connectie. je zult dus OF je query moeten synchroniseren OF een databaseconnectie aan je thread moeten toevoegen.

Anoniem: 116711

Topicstarter
maar dan heb ik dus de hele database in de thread EN in het hoofdprogramma (deze heefd die nl. ook nodig voor andere zaken)?
synchronizen lijkt me niet de optie want ik zet het juist in een thread omdat die queries zoveel tijd vreten (online database).

btw: ik heb nu private fields aangemaakt, die getusername niet gesynchronized en updatememo wel gesynchronized en het hoofdprogramma zit nu idd niet meer te wachten! :)

  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
Anoniem: 116711 schreef op 30 september 2004 @ 12:20:
maar dan heb ik dus de hele database in de thread EN in het hoofdprogramma (deze heefd die nl. ook nodig voor andere zaken)?
Nee. Je hebt ALLEEN een connectie nodig in je Thread en daarbij een query-object. Deze connectie in de Thread kun je dan ook alleen maar in je thread gebruiken.
synchronizen lijkt me niet de optie want ik zet het juist in een thread omdat die queries zoveel tijd vreten (online database).
Dat hoeft dus niet als je een connectie hebt in je Thread. De connecties lopen naast elkaar. Het komt er dus in feite op neer dat je Thread een eigen gebruiker is die tegelijk op de database kan met de hoofdthread.
btw: ik heb nu private fields aangemaakt, die getusername niet gesynchronized en updatememo wel gesynchronized en het hoofdprogramma zit nu idd niet meer te wachten! :)
Dat klinkt goed. Hoe vaak roept je thread eigenlijk die UpdateMemo aan? Ik neem even aan dat je niet de hele tijd de query in de Thread uitvoert en daarna UpdateMemo doet, maar met tussenpozen?

Anoniem: 116711

Topicstarter
sry ff opnieuw tiepen

[ Voor 94% gewijzigd door Anoniem: 116711 op 30-09-2004 13:17 ]


  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
Prik me anders ff op MSN

Anoniem: 116711

Topicstarter
Nee. Je hebt ALLEEN een connectie nodig in je Thread en daarbij een query-object. Deze connectie in de Thread kun je dan ook alleen maar in je thread gebruiken.
Nee, ik heb die connectie ook nodig in het hoofdprogramma, deze moet nl. ook queries uitvoeren op dezelfde database, alleen andere.
Ik neem aan dat je ongeveer snapt wat ik aant bouwen ben? In het hoofdprogramma moeten iig user-gegevens en andere zaken gewijzigd kunnen worden en daarvoor is ook een database connectie nodig.
Dat klinkt goed. Hoe vaak roept je thread eigenlijk die UpdateMemo aan? Ik neem even aan dat je niet de hele tijd de query in de Thread uitvoert en daarna UpdateMemo doet, maar met tussenposen?
De thread kijkt alleen of er events in fEventQueue staan die verwerkt moeten worden en zodra dit het geval is roept hij de UpdateMemo aan.
Deze events komen in de queue dmv een event (sry voor al die events) die nDbListener uitspuugt. Dit heb ik inelkaar geflanst met PostgreSQL waar je rules kunt creeeren bij tabellen zodra er ge-update, ge-select of ge-insert wordt. De query wordt dus alleen uitgevoerd als dit nodig is.
Dat hoeft dus niet als je een connectie hebt in je Thread. De connecties lopen naast elkaar. Het komt er dus in feite op neer dat je Thread een eigen gebruiker is die tegelijk op de database kan met de hoofdthread.
Hier loop ik tegen een probleem aan!
ik heb nu 2 database connecties, 1 op een datamodule in het hoofdprogramma (deze doet overigens nog nix maar gewoon om te testen of 2 paralelle connecties werken) en 1 in de thread die ik creeer zodra de thread start.
Nu krijg ik een database error: 'duplicate database name'.
Betekend dit dat hij geen 2 connecties vreet?

ps: de namen van de componenten zijn anders, het gaat hier om de databasename property die aangeeft wat de naam is van de db waar hij op moet gaan inloggen!

Anoniem: 113889

Robbemans schreef op 30 september 2004 @ 12:02:
[...]
ELKE THREAD MOET EEN EIGEN CONNECTIE HEBBEN NAAR JE DATABASE!
Heeft iemand dit wel eens geprobeerd met BDE-componenten ? Dit zijn namelijk venster componenten en volgens het boekje zouden die gesyncht moeten worden. In deze gevallen pak ik altijd ADO.

Edit:
Nu krijg ik een database error: 'duplicate database name'.
Betekend dit dat hij geen 2 connecties vreet?
De aliasses moeten verschillend zijn. Je kan je threads bv voorzien van een ID en die in de alias verwerken.

[ Voor 25% gewijzigd door Anoniem: 113889 op 30-09-2004 13:43 ]


Anoniem: 116711

Topicstarter
ik gebruik PostgresDAC van microOLAP

http://microolap.com/dac/pgsql/index.htm

dit is de enige set componenten die ik heb kunnen vinden die een listener component heeft voor postgreSQL databases. dwz dat die die notifies opvangt van de db.

Anoniem: 116711

Topicstarter
De aliasses moeten verschillend zijn. Je kan je threads bv voorzien van een ID en die in de alias verwerken.
nee, de DatabaseName poperty moet hetzelfde zijn anders krijg je nl de fout database (bladiebla) not found on hostname..
het gaat hier immers om dezelfde database.

  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
Heeft die component suite alleen een Database component of ook een Connection component? Die heb je nodig in je thread.

Anoniem: 116711

Topicstarter
helaas, die heeft geen connection component.

Edit:
sowieso moet ik aan dat listener component een database koppelen dus met een connection component kom ik sowieso niet uit de voeten.

[ Voor 74% gewijzigd door Anoniem: 116711 op 30-09-2004 13:51 ]


Anoniem: 113889

Anoniem: 116711 schreef op 30 september 2004 @ 13:46:
[...]


nee, de DatabaseName poperty moet hetzelfde zijn anders krijg je nl de fout database (bladiebla) not found on hostname..
het gaat hier immers om dezelfde database.
Ik weet niet hoe dit geregeld is in de componenten die je gebruikt. In de BDE-componenten is er zowel een database name (database op server) als een alias (database hernoeming op client). Bij gebruik van de BDE mag de database naam gelijk zijn, als de alias naam maar verschilt.

Edit:
Kan je de TPSQL componenten op een form droppen ? Staat er iets in de documentatie hoe threadsafe ze zijn ?

[ Voor 10% gewijzigd door Anoniem: 113889 op 30-09-2004 13:54 ]


Anoniem: 116711

Topicstarter
noop, dit is ook geen bde-component, ik maak ook geen gebruik van de bde-administrator hier. deze database component heeft geen alias property.

  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
Heb je de source erbij? Dan kun je tracen wat er exact mis gaat bij de 2e database. Ik kan me niet voorstellen dat je maar 1 connectie mag hebben...

  • cimbom
  • Registratie: Juni 2001
  • Laatst online: 26-04-2024

cimbom

Just Kidding

Je creert gewoon een nieuwe connection/databse component in create van je thread. Je vult de parametrs/connectionstring van dat component. Geeft databse property een unieke naam.
Nu creer je query component en coppel je deze met je connection/database component die je net creerde.

In je destructor van Thread geef je deze twee componenten vrij.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Moest thread een AOwner hebben? Whatever dacht wel;
contructor TThread.Create( AOwner:TComponent; connectionstring : String)
begin
  inherited Create(AOwner);
  FDatabase := TDatabase.Create(nil);

// Can ook parameters zijn ht gaat om het idee
  FDatabase.Conectionstring := connectionstring ;

  FDatabase.DatabaseName := 'Verzin maar een naam';
 

  FQuery := TQuery.Create(nil);

  //FQuery.Connection := FDatabase; of
    FQuery.DatabaseName := FDatabase.DatabaseName;  

end;

destructor Destroy
begin
  FQuery.Free;
  FDatabase.Free;
 inherited;
end;



FQuery en FDatabse zijn private variabelen van je Thread.
Propertynamen weet ik niet zo uit mijn hoofd voor jouw componenten.
Daarom heb ik maar wat verzonnen, als het maar duidelijk is wat we bedoelen.

edit:

inherited vergeten.. Ja ik tikte wat in.

[ Voor 8% gewijzigd door cimbom op 30-09-2004 13:59 ]


  • cimbom
  • Registratie: Juni 2001
  • Laatst online: 26-04-2024

cimbom

Just Kidding

Robbemans schreef op 30 september 2004 @ 13:55:
Heb je de source erbij? Dan kun je tracen wat er exact mis gaat bij de 2e database. Ik kan me niet voorstellen dat je maar 1 connectie mag hebben...
Nee je databse naam moet uniek zijn. Bij BDE geldt dit ook. Bij die databse componenten kun je databse naam geven die moet uniek zijn. Dus als je een andere databse component creert dan geef je database een andere naam in die property. Ik weet niet of hij nou BDE gebruikt maar lijkt er wel sterk op.

Anoniem: 116711

Topicstarter
code:
1
2
3
4
5
6
7
8
9
procedure EventHandler.InitDatabase;
begin
  fDbConnection := TPSQLDatabase.Create(nil);
  fDbConnection.DatabaseName := 'main';
  fDbConnection.Name := 'main2';
  fDbConnection.Host := 'pgsql.progressix.net';
  fDbConnection.UserName := 'test_user';
  fDbConnection.Open
end;


dit is de code waar ik die 2de db connectie creeer. als ik hem debug crasht die op:
code:
1
fDbConnection.DatabaseName := 'main';

  • Robbemans
  • Registratie: November 2003
  • Laatst online: 29-01 14:52
cimbom schreef op 30 september 2004 @ 13:57:
[...]


Nee je databse naam moet uniek zijn. Bij BDE geldt dit ook. Bij die databse componenten kun je databse naam geven die moet uniek zijn. Dus als je een andere databse component creert dan geef je database een andere naam in die property. Ik weet niet of hij nou BDE gebruikt maar lijkt er wel sterk op.
Ik ken zijn componenten niet, dus vandaar mijn vraag. Bij de BDE moet ie idd uniek zijn, maar daar werkt ie zo te horen niet mee...

Anoniem: 113889

Anoniem: 116711 schreef op 30 september 2004 @ 13:53:
noop, dit is ook geen bde-component, ik maak ook geen gebruik van de bde-administrator hier. deze database component heeft geen alias property.
Yikes, en dan niet 2x in mogen loggen :( . Voor the hulp-threadjes zou ik voor ADO met ODBC gaan. Je moet ADO via z'n typelib gebruiken en niet de via de bijgeleverde Delphi-componenten; dan zit je namelijk weer aan de VCL vast.

Anoniem: 116711

Topicstarter
Voor the hulp-threadjes zou ik voor ADO met ODBC gaan.
Helaas, want dan heb ik dit listener component (TPSQLNotify) niet en die heb ik juist nodig om te kijken wanneer er iets gebeurd op de database. Anders moet ik die thread constant laten query-en of er iets gewijzigd is.

ps: robbemans, kheb je ff toegevoegd aan de msn, ma mss handiger om dat hier ff af te handelen ivm de rest die zich inmiddels in deze discussie heeft gemengd.

  • cimbom
  • Registratie: Juni 2001
  • Laatst online: 26-04-2024

cimbom

Just Kidding

Anoniem: 116711 schreef op 30 september 2004 @ 14:00:
code:
1
2
3
4
5
6
7
8
9
procedure EventHandler.InitDatabase;
begin
  fDbConnection := TPSQLDatabase.Create(nil);
  fDbConnection.DatabaseName := 'main';
  fDbConnection.Name := 'main2';
  fDbConnection.Host := 'pgsql.progressix.net';
  fDbConnection.UserName := 'test_user';
  fDbConnection.Open
end;


dit is de code waar ik die 2de db connectie creeer. als ik hem debug crasht die op:
code:
1
fDbConnection.DatabaseName := 'main';
laat me raden Databsename van je connectiecomponent in datamodule heet ook main.

probeer
code:
1
fDbConnection.DatabaseName := 'main2';

dan maar

of die property is niet bedoeld voor alias maar dat het echt naar database main gaat in DBserver

[ Voor 12% gewijzigd door cimbom op 30-09-2004 14:09 ]


  • cimbom
  • Registratie: Juni 2001
  • Laatst online: 26-04-2024

cimbom

Just Kidding

http://microolap.com/dac/pgsql/help/index.htm

DatabaseName Published Specifies the name of the database to associate with this database component.

Schijnbaar is het niet alias die ermee bedoeld wordt maar naar welke databse in ser je wil connecten, toch?

edit:

OOh nee w8 even. hij heeft ook params property zoals BDE Tdatabase component.
Waarschijnlijk is het toch alias name die bedoeld wordt met property DatabaseName

[ Voor 26% gewijzigd door cimbom op 30-09-2004 14:20 ]


Anoniem: 113889

Anoniem: 116711 schreef op 30 september 2004 @ 14:05:
[...]


Helaas, want dan heb ik dit listener component (TPSQLNotify) niet en die heb ik juist nodig om te kijken wanneer er iets gebeurd op de database. Anders moet ik die thread constant laten query-en of er iets gewijzigd is.
TPSQLNotify ben je volgens mij sowieso kwijt als de componenten van die zo'n icoon-achtige dingetjes zijn. Een data module is een venster (erft van TForm). Als je van die icoontjes hebt of een data module gebruikt is het zaakje niet multithreadproof.

Edit:
Listen en Notify zijn onderdelen van de PostgreSQL. Via SQL kan je dus uiteindelijk zelf gaan monitoren.

[ Voor 17% gewijzigd door Anoniem: 113889 op 30-09-2004 14:26 ]


Anoniem: 116711

Topicstarter
okee, ten eerste nog maar es de reden waarom ik dit in een thread wil: ik wil niet dat het hoofdprogramma moet wachten op queries, de db staat nl online en dit kost TE veel tijd om hier steeds op te wachten.

conclusie tot nu toe:
het gaat er op lijken dat ik 2 applicaties moet gaan schrijven die onderling met elkaar gaan communiceren aangezien 2 database connecties in 1 applicatie NIET mogelijk is. ik ga nu es wat info opzoeken op internet over hoe ik dit voor elkaar ga krijgen. vorderingen volgen hier..
alvast bedankt voor alle replys tot nu toe! :)
Pagina: 1