[Delphi] DCOM server geeft fout bij sluiten

Pagina: 1
Acties:
  • 262 views sinds 30-01-2008
  • Reageer

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb een DCOM server met o.a. 1 gewone DataModule en 1 RemoteDataModule.

Op de gewone DataModule zit de ADOConnection die verbinding maakt met een MSSQL server in de OnCreate van de DataModule.
Op de RemoteDataModule zit een ADOQuery en een DataSetProvider.

De gewone DataModule is auto-create en is er dus altijd. Er wordt dus ook maar 1 instansie van aangemaakt.

De RemoteDataModule wordt per verbinding (client) aangemaakt (ciMultiInstance, tmSingle). Dit werk allemaal zeer goed. Als alle clients de verbinding hebben verbroken, kun je de server perfect sluiten. Is er een client nog actief en je wilt de server sluiten dan krijg je een waarschuwing dat er nog active com-objecten zijn.

Kies je bij die waarschuwing ervoor om de server toch te sluiten dan volgt er een AV en een run-time error. De debugger weet niet waar deze plaats vind in de code en doormiddel van F7/F8 in Delphi tijdens debug kom je ook geen stap verder.

Het vreemde is ook dat je die error's alleen krijgt als een client een SELECT query heeft uitgevoerd in zijn sessie en deze client is bij het sluiten nog actief. Heeft de client niks gedaan (alleen verbinding gemaakt) of alleen UPDATE/INSERT/enz queries uitgevoerd en je sluit dan de server dan is er niks aan de hand.

In de Unit van de RemoteDataModule zit geen eigen code. Het gaat volgens mij mis nadat de OnDestroy event is geweest van de RemoteDataModule.

Hoe kan dit en hoe is dit op te lossen?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Gokje: de DataModule wordt voor de laatste RemoteDataModule vrijgegeven? Proberen met breakpoints in OnDestroy in DM en RDM.
Als dat zo is moet je denk ik in de OnDestroy van de DM eerst de RDM's vrijgeven. Kijk daar ook eens hoeveel datasets je connectie nog heeft (en misschien ook sluiten).

Zoals ik al zei. gokje

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
De DataModule wordt eerst vrij gegeven idd. Dat moet dus niet. Maar hoe zorg ik ervoor dat hij bij sluiten eerst alle open RemoteDataModules vrij geeft, en dan pas de gewone DataModule.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
ranzine manier (in OnDestroy ofzo). Ik denk dat je AV optreed door de ADOQuery. Zo sluit je je queries en laat je windows de zooi opruimen (lees RDM).
code:
1
2
3
4
5
6
7
8
9
10
var i : integer;
begin
  for i := ADOConnection1.DataSetCount - 1 downto 0 do begin
    try
      ADOConnection1.DataSets[i].Close;
      ADOConnection1.DataSets[i].Free;
    except
    end;
  end;
end;


Als de RDM met owner worden gecreeerd (TRDM.Create(DM);) kan het volgende ook. (Is een betere methode).
code:
1
2
3
4
5
6
7
8
9
var i : integer;
begin
  for i := ADOConnection1.DataSetCount - 1 downto 0 do begin
    try
      ADOConnection1.DataSets[i].Owner.Free;
    except
    end;
  end;
end;

.Owner is dan de RDM.

Dit hele verhaal kan omdat TADOConnection die array heeft met datasets. Ook niet actieve datasets staan daarin (net ff geprobeerd).

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Heb even getest: heb de ADOConnection verplaatst naar de RemoteDataModule, zodat elke client een eigen ADOConnection heeft. En vervolgens heb ik de gewone DataModule uit het project gegooit. Helaas zonder resultaat, nog steeds de AV tijdens sluiten met active clients.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Werkt die 2e ook niet?

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ook met de code hier boven in het zelfde project (dus die zonder de gewone DataModules) krijg ik een AV en een run-time error bij sluiten van server als er nog clients verbonden zijn die een resultaat-query (SELECT) hebben uitgevoerd.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Post anders wat als het niet teveel is of mail het me (mark@elissen.com)

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Elissen schreef op 10 augustus 2002 @ 20:08:
Post anders wat als het niet teveel is of mail het me (mark@elissen.com)
Denk niet dat dat echt gaat. Hoort een database bij en het project is voor commerciele dooleinden.

Kom anders even op ICQ (eventueel: wat is je MSN), dat gaat wat makkelijker.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Tom-my
  • Registratie: November 2000
  • Laatst online: 19-06 09:25

Tom-my

w03iz0rz

offtopic:
Hey jelmer vos :), eigenlijk is dat forum crossposten he ;)

"Then there was the man who drowned crossing a stream with an average depth of six inches."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ben weer wat verder.

Ik heb alle code achter de RDM weggehaald en ook de verwijzigen (uses) naar andere forms en DM's. Maar de server werkt natuurlijk nog wel gewoon.

Nu treed de fout alleen op als ik de ThreadingModel van de RDM op tmSingle zet. Zet ik hem op tmApartment dan gaat alles goed!

Hoe kan dit, kan iemand mij misschien meer duidelijkheid geven over dit probleem. En wat precies het beste is. Ik zit namelijk met het probleem dat de RDM logging uitvoert naar de MainForm van de server, zodat je kan zien wat er gebeurd.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • yodax
  • Registratie: Januari 2000
  • Laatst online: 28-04 08:47
Als je het adres hebt waar de AV optreed, kun je door een memory map te maken uitrekenen op welke plek in je code de fout optreed.

Dat de debugger de plek niet kan vinden zou kunnen worden opgelost door use debug dcu's aan te zetten. De fout zit dan waarschijnlijk in de System Unit. Door dan de call stack te gebruiken kun je kijken welk object de fout laat doen optreden.

Voor het uitrekenen van de plaats van de fout zijn programmas te vinden, en anders staat er een beschrijving naar ik geloof op community.borland.com. Even uit mijn hoofd: je moest de off-set van het hexedecimale adres afstrekken en die in de map.file opzoeken, die geeft aan welk stuk code het probleem geeft.

Ik ben op verschijdene seminars geweest, waar behoorlijk bekende delphi guru's waaren zoals Marco Cantu en Cary Jensen. Zij konden geen van allen duidelijk uitleggen welk model goed is voor COM.
Persoonlijk vond ik het stuk uit de Developer Guide wel goed (zit bij de enterprise edition)

O ja, voor de debug dcu's heb je volgens mij ook de enterprise edition nodig.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik weet onderhand waar de fout optreed dmv debug DCU's. Is uit eindelijk idd in de system.pas (in een stukje ASM code). Het heeft te maken met releasen van interfaces.

Volgens mij doe ik iets fout. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

yodax schreef op 13 augustus 2002 @ 11:20:
Als je het adres hebt waar de AV optreed, kun je door een memory map te maken uitrekenen op welke plek in je code de fout optreed.
Of Menu -> Search -> Find Error en dan het adres invullen. Werkt alleen als je gecompiled heb en de compile versie niet anders is dan de versie waar de error in voorkomt.

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Opzich maakt de locatie van de fout niet zoveel uit.
Ik weet namelijk waardoor het komt denk ik.

Elke client krijgt een eigen RDM. Deze zit in een eigen thread. Nou kan ik niet zomaar gegevens van een RDM naar de VCL main thread (de MainForm) sturen. Dit doe ik in mijn geval voor logging. Maar hoe los je dat op. Ik wil toch kunnen zien in de MainForm van mijn server wat er gebeurd bij de verschillende RDM's (clients).

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Delphi schreef op 13 augustus 2002 @ 11:38:
Opzich maakt de locatie van de fout niet zoveel uit.
Ik weet namelijk waardoor het komt denk ik.

Elke client krijgt een eigen RDM. Deze zit in een eigen thread. Nou kan ik niet zomaar gegevens van een RDM naar de VCL main thread (de MainForm) sturen. Dit doe ik in mijn geval voor logging. Maar hoe los je dat op. Ik wil toch kunnen zien in de MainForm van mijn server wat er gebeurd bij de verschillende RDM's (clients).
Waarom kan je het in jouw geval niet zomaar? Omdat het niet thread safe is? Of omdat je een interface naar een ander apartment wil brengen?

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik gebruik tmApartment, de Help zegt dit over tmApartment:
COM ensures that any instance of the COM object services one request at a time. Different objects from the same server can be called on different threads, but each object is called only from that one thread. Instance data is safe, global data must be protected using critical sections or some other form of serialization. The threads local variables are reliable across multiple calls.
Ik moet dus denken om de global data. Is dat niet gelijk aan een functie die door elke RDM (client) kan worden aangeroepen?Ik heb namelijk gewoon een functie in de MainForm zitten voor logging. Deze functie wordt gewoon door een RDM aangeroepen als een clietn bijvoorbeeld een query uitvoert, of data ophaalt.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 31-08 21:58

Delphi32

Heading for the gates of Eden

Ik was aan het zoeken voor je maar werd steeds onderbroken. Zoek es op Synchronize. Als je met threads & VCL werkt moet je synchronizen.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Maar ik weet niet zeker of dat wat uitmaakt. Zal het proberen.
En hoe synchronize je een functie met parameters?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Niet thread safe betekend dat.

Zoals de help al aangeeft kan je dat verhelpen door er o.a. een critical section van te maken. Dus in je MainForm.Log methode TCriticalSection gebruiken.

Met single heb je daar geen last van omdat het altijd maar 1 thread is.

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Kan ik simpel naar ThreadinModel tmSingle overschakelen door dit aan te passen:
code:
1
2
3
initialization
  TComponentFactory.Create(ComServer, TDefaultModule,
    Class_DefaultModule, ciMultiInstance, tmApartment);

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Maar ik weet niet zeker of dat wat uitmaakt. Zal het proberen.
Synchronize is een methode van TThread. Niet van toepassing hier dus.
En hoe synchronize je een functie met parameters?
Niet. Je kan alleen een procedure meegeven. Gebruik variablen in je klasse ipv parameters.

En Synchronize zet eigenlijk alleen een cirtical section om de procedure heen die je meegeeft. Dat kan je dus simpel zelf gewoon doen :)

[ Voor 0% gewijzigd door LordLarry op 13-08-2002 12:13 . Reden: toevoeging ]

We adore chaos because we like to restore order - M.C. Escher


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Delphi schreef op 13 augustus 2002 @ 12:11:
Kan ik simpel naar ThreadinModel tmSingle overschakelen door dit aan te passen:
code:
1
2
3
initialization
  TComponentFactory.Create(ComServer, TDefaultModule,
    Class_DefaultModule, ciMultiInstance, tmApartment);
Ja

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Oke, bedankt voor de reacties. Ik zal weer even testen. :)

Eerst maar es een TCriticalSection maken en starten/stoppen in de AddLog functie van de MainForm.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Weer wat verder:

Met ThreadingModel tmSingle: alles werkt perfect, alleen diezelfde fout als hierboven beschreven bij afsluiten.

Met ThreadingModel tmApartment: geen fouten bij afsluiten, maar ik mag geen methods uit de MainForm aanroepen vanuit een RDM. Ook niet met een CriticalSection object in die method.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Met welke parameters roep je die functie aan? Zitten daar interfaces tussen?

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
LordLarry schreef op 13 augustus 2002 @ 13:38:
Met welke parameters roep je die functie aan? Zitten daar interfaces tussen?
Nope, gewoon een paar strings, en een eigen type (set). Niks bijzonders.

Bij tmSingle werkt alles goed, dit klopt ook als ik de Help erop na sla en op internet zoek. Bij tmSingle hoef je niet om globale data te denken, dus ook niet om functies in de VCL thread. tmSingle werkt volgens gewoon niet met threads toch?

Als ik zoek op internet naar tmApartment dan moet ik wel degelijk denken om globale data en methods. Dit staat ook in de help. Maar hoe dit dan moet weet ik niet.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Een single heeft 1 thread, dus je hebt inderdaad minder zorgen.

Als je de TCriticalSection goed gebruikt hebt is het thread safe en kan het daar niet aan liggen.

Wat is de foutmelding precies en waarneer komt ie voor? Gebeurd het ook als je het loggen er gewoon even uitsloopt, maar dat je m wel op Apartment laat staan?

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Heb even een test applicatie gemaakt. Een server en een client. De server wel even registeren door hem 1 maal te starten of starten met parameter /regserver. De server kun je de-registreren door hem de starten met parameter /unregserver.

De server is nu tmSingle. Dit werkt goed, maar laat de client die SELECT query maar es uitvoeren, en dan de server sluiten ZONDER de client de verbreken.
De server kan ook tmApartment, maar dan werken die procedures uit de MainForm niet meer. Dat is logisch, vanwege de VCL main thread.

http://httpd.chello.nl/~j.vos6/dcomtest.zip (726 KB, inclusief de exe's)

edit:
Ik draai de laatste versie van MDAC

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Ik denk dat het met TCriticalSection niet gaat lukken. Als je TCriticalSection gebruikt gaan alle threads (van de RDM's) op alkaar wachten, wat precies is wat je wilt. Echter, je hebt ook nog de thread van de VCL. Je moet op de een of andere manier synchroniseren met de thread van de vcl. (Kijk eens naar de code van TThread.Synchronise in Classes.pas).
Het kan met TCriticalSection als je vanuit de vcl mbv dezelfde TCriticalSection kijk of er items in een soort van queue staan en die vervolgens in een memo ofzo zetten.

ga nu kijken naar je voorbeeld

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik denk dan dat het makkelijker is om tmSingle te gebruiken en die afsluit bug na een SELECT query eruit halen.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Krijg de exe's niet aan de praat. Ik heb de server geregistreerd, maar ik krijg nog steeds 'RPC Server Unavailable'. Nou heb ik niet veel verstand van remote data modules, maar hercompileren hielp ook niet in iedergeval

We adore chaos because we like to restore order - M.C. Escher


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
je moet de computernaam wijzigen in het dcom-object van de client.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Elissen schreef op 13 augustus 2002 @ 14:36:
je moet de computernaam wijzigen in het dcom-object van de client.
Staat die nog verkeerd? uuuhmm, moest localhost zijn. :)

Heb hem ff opnieuw geupload met computer naam "LOCALHOST".

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Dit werkt met tmApartment:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
procedure AddConnection;
procedure DelConnection;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

var
  CS : TCriticalSection;
  Connections: Integer;

procedure AddConnection;
begin
  CS.Enter;
  Inc(Connections);
  CS.Leave;
end;

procedure DelConnection;
begin
  CS.Enter;
  Dec(Connections);
  CS.Leave;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Connections := 0;
  CS := TCriticalSection.Create;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  CS.Destroy;
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
begin
  CS.Enter;
  Label2.Caption := 'Connections: '+ IntToStr(Connections);
  CS.Leave;
end;

Ik heb de counter uit het formulier getrokken. De counter word beveiligd door de Critical Section. Een timer ververst nu de de gegevens op het formulier.

Heb geen AV's meer gezien. Jelmer, ik mail je nu alles.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik liet (in dit voorbeeld) die counters binnen de form en maakte per procedure een CriticalSection aan. Maar dit zit er beter uit, ga er mee aan de slag.

Toch vind ik het vaag dat tmSingle AV's geeft.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Laat ff weten of het lukt.

  • yodax
  • Registratie: Januari 2000
  • Laatst online: 28-04 08:47
Zo los ik logging op in een multithreaded app:

Het is niet volledig, aangezien het commerciele code is, maar het helpt je iig wel op weg.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var
   CSLog: TCriticalSection;
   LogList: TList;

type
   TLogListItem = record
      LogText: string;
      LogCode, LogLevel: Integer;
   end;

procedure TLog.Add(const LogText: string; const LogCode, LogLevel: Integer);
var
   LogListItem: ^TLogListItem;
begin
   try
      New(LogListItem);
      LogListItem^.LogText := LogText;
      LogListItem^.LogCode := LogCode;
      LogListItem^.LogLevel := LogLevel;
      CSLog.Enter;
      try
         LogList.Add(LogListItem);
      finally
         CSLog.Leave;
      end;
   except
      AddOld('Can not add log message to global log list',999,1);
   end;
end;

procedure TLog.RefreshLog;
var
   Idx: integer;
   mLogList: TList;
begin
   if LogList.Count > 0 then
   begin
      mLogList := TList.Create;
      try
         CSLog.Enter;
         try
            if LogList.Count > 0 then
            begin
               for Idx := LogList.Count - 1 downto 0 do
               begin
                  mLogList.Add(LogList.Items[Idx]);
                  LogList.Delete(Idx);
               end;
            end;
         finally
            CSLog.Leave;
         end;

         for Idx := mLogList.Count - 1 downto 0 do
         begin
            AddOld(TLogListItem(mLogList.Items[Idx]^).LogText,
               TLogListItem(mLogList.Items[Idx]^).LogCode,
               TLogListItem(mLogList.Items[Idx]^).LogLevel
               );
            TLogListItem(mLogList.Items[Idx]^).LogText := '';
            Dispose(mLogList.Items[Idx]);
            mLogList.Delete(Idx);
         end;
      finally
         mLogList.Free;
      end;
   end;
end;


Je kan nu vanuit elke thread de procedure log(...) aanroepen. De globale data wordt namelijk beschermd.

Dit werkt bij mij in meerder multithreaded apps perfect.

De refresh functie kan je het beste in een timer aanroepen, bijvoorbeeld om de seconde. Anders staan al je threads te wachten terwijl jij de log lijst uit memory moved. Hoewel het behoorlijk snel gaat, het is namelijk alleen het kopieeren van de pointers uit de list.

  • yodax
  • Registratie: Januari 2000
  • Laatst online: 28-04 08:47
Het probleem met jouw methode is alleen dat je door je hele thread heen al je data moet beschremen met CS. Je mag er dus geen 1 vergeten. Het is ook niet efficient.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Werkt perfect, bedankt man! :)

Maar ik mag nu zeker niet meer 1 gewone DataModule gebruiken voor alle RemoteDataModules om bijvoorbeeld een ADOConnection op te zetten? Zodat alle RemoteDataModules 1 ADOConnection gebruiken.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
yodax schreef op 13 augustus 2002 @ 14:56:
[...]


Het probleem met jouw methode is alleen dat je door je hele thread heen al je data moet beschremen met CS. Je mag er dus geen 1 vergeten. Het is ook niet efficient.
Mijn oplossing was specifiek voor Jelmer's/Delphi's probleem. Dit was puur voor die ene counter en daarvoor voldoet het. Als je iid een uigebreider loggingsysteem wilt kan je beter iets maken zoals jouw voorbeeld. Vergeet niet dat geposte code ook een voorbeeld is. Nu staan hier twee stukken code van verschillende niveau's waar anderen naar kunnen kijken:). Ik denk dat er nu leuke informatie over multi-threading in dit topic staat.

Terug naar het probleem van de topicstarter:
Het punt waar het mis ging is het feit dat de vcl een eigen thread heeft. Je kunt alle thread synchroniseren, maar dan moet je de vcl ook meenemen.
Als je zelf een eigen thread maakt (afgeleidde van TThread) heb je een methode Synchonise die dat synchroniseren met de vcl voor je doet.
En waar die AV vandaan komt? Al sla je me dood.. (laat dat laatste maar zitten trouwens)
Delphi schreef op 13 augustus 2002 @ 15:49:
Werkt perfect, bedankt man! :)

Maar ik mag nu zeker niet meer 1 gewone DataModule gebruiken voor alle RemoteDataModules om bijvoorbeeld een ADOConnection op te zetten? Zodat alle RemoteDataModules 1 ADOConnection gebruiken.
Kijk eens in de Delphi help bij 'Using the main VCL/CLX thread', topic group 'Building applications with Delphi'. Ik denk wel dat het kan (weet het NIET ZEKER!!). Het is ook afkankelijk van de database-driver!.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Oke, zal het es opzoeken.

Wat mijn gedachte is: je kunt heel simpel meerdere ADOQuery's op 1 ADOConnection kopppelen. Maar nou zit die ADOConnection op een DataModule en die ADOQuery's op verschillende RDM's.

Zelf denk ik niet dat het kan, omdat je namelijk gewoon de DataModule benaderd, en dan pas de ADOConnection. DIe DataModule is een onderdeel van de VCL main thread, toch?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Elissen
  • Registratie: Januari 2000
  • Laatst online: 27-07 15:54
Dat is inderdaad een probleem. De query en connectie bevinden zich dan in verschillende threads, echter in de help staat dat je wel moet synchroniseren voor bijvoorbeeld het koppelen van een dataset met een datasource. Echter, je hoeft niet te synchoniseren voor het raadplagen van de data.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Dit staat erover in de Help:
Data access components are thread-safe as follows: For BDE-enabled datasets, each thread must have its own database session component. The one exception to this is when you are using Access drivers, which are built using a Microsoft library that is not thread-safe. For dbDirect, as long as the vendor client library is thread-safe, the dbDirect components will be thread-safe. ADO and InterbaseExpress components are thread-safe.

When using data access components, you must still wrap all calls that involve data-aware controls in the Synchronize method. Thus, for example, you need to synchronize calls that link a data control to a dataset by setting the DataSet property of the data source object, but you dont need to synchronize to access the data in a field of the dataset.

"The shell stopped unexpectedly and Explorer.exe was restarted."

Pagina: 1