![]() |
Synchronize blockiert Anwendung
Hallo zusammen,
ich bin gerade am verzweifeln und bin sicher, dass es nur irgendwo eine Kleinigkeit ist. Ich habe einen Treiber auf das Nötigste zusammengestrichen. Also nicht wundern, dass es etwas sinnfrei wirkt. Das Problem ist, dass ich in einer DLL einen Thread starte. Sobald der aber im Execute-Teill das Synchronize() aufruft, bleibt er an der Stelle hängen. Ursprünglich ist es aus Delphi XE, es hängt aber auch in XE 10.2. Hier der Code Die dll
Delphi-Quellcode:
Der Prozesshandler
library UV;
uses SysUtils, Windows, Classes, uProcessUv in 'uProcessUv.pas', uThreadUv in 'uThreadUv.pas'; {$R *.res} exports SetCommandW; end.
Delphi-Quellcode:
Der Threadhandler
unit uProcessUv;
interface uses uThreadUv; type TProcessUv = class procedure Start; private constructor Create; destructor Destroy; override; procedure ShowStatus(sValue:String); public end; procedure SetCommandW; stdcall; implementation uses Sysutils; var ThreadUV : TThreadUv; ProcessUv: TProcessUv; procedure SetCommandW; stdcall; // Erlaubt das Senden von Kommandos als WideString und gibt das Ergebnis ebendfalls als WideString zurück begin if not assigned(ProcessUv) then begin ProcessUv := TProcessUv.Create; ProcessUv.Start; end; end; constructor TProcessUv.Create; begin inherited; end; destructor TProcessUv.Destroy; begin inherited; end; procedure TProcessUv.ShowStatus(sValue: String); // Synchronisert Statusmeldung vom ThreadUVv begin // Mach was mit sValue end; procedure TProcessUv.Start; begin if not assigned (ThreadUv) then begin ThreadUv := TThreadUv.Create; // ThreadUv.StatusEvent := ProcessUv.ShowStatus; ThreadUv.Start; end; end; end.
Delphi-Quellcode:
und zuletzt der Aufruf
unit uThreadUv;
interface uses Classes; type TThreadString = procedure(sValue: String) of Object; TThreadUV = class(TThread) protected procedure Execute; override; private { Private-Deklarationen } FStatus: String; FStatusEvent: TThreadString; procedure SyncStatusEvent; public property StatusEvent: TThreadString read FStatusEvent write FStatusEvent; constructor Create; destructor Destroy; override; end; implementation { TThreadUV } constructor TThreadUV.Create; begin inherited Create(true); // muss auf true stehen damit Aufruf mit Start funktioniert end; destructor TThreadUV.Destroy; begin Terminate; inherited; end; procedure TThreadUV.SyncStatusEvent; // Übergeordneten Prozess Status mitteilen begin if assigned(FStatusEvent) then FStatusEvent(FStatus); end; procedure TThreadUV.Execute; begin FStatus := 'So ein Mist'; Synchronize(syncStatusEvent); // Hier hängt es sich auf while not Terminated do begin sleep(500); Terminate; end; end; end.
Delphi-Quellcode:
Egal, ob ich an Synchronice etwas assigned habe oder nicht, hängt sich die Anwendung beim Aufruf von
procedure SetCommandW; stdcall; external 'UV.dll';
procedure TForm6.Button1Click(Sender: TObject); begin SetCommandW; end;
Delphi-Quellcode:
auf
Synchronize(syncStatusEvent);
Kann mir jemand sagen was ich falsch mache. Vielen Dank Gerd |
AW: Synchronize blockiert Anwendung
|
AW: Synchronize blockiert Anwendung
Kompilierst du mit Laufzeitpackages oder ohne?
Wenn ohne, dann hat die DLL ihre eigene RTL/VCL und deren eigenen globalen Variablen. Die EXE hat ebenfalls ihre eigene RTL/VCL/Variablen. Also das Synchronize der DLL weiß nichts von der VCL in der EXE und kann demnach nicht richtig arbeiten. * mit Laufzeitpackages die EXE und DLL kompilieren * oder kein Synchronize in der DLL (z.B. per Callback in der EXE das Synchronize) * oder siehe CheckSynchronize in Antwort #4 von ![]() |
AW: Synchronize blockiert Anwendung
Zitat:
Das blöde ist, in der damaligen Anwendung habe ich es zum Laufen gebracht und gestern und heute eigentlich gleich implememtiert und jetzt hänge ich wieder an derselben Stelle. Das Synchronize soll nicht rauf zur EXE sondern raus aus dem Thread un dim nächsten Schritt entweder auf eine ANzeige oder zur Exe. |
AW: Synchronize blockiert Anwendung
So jetzt habe ich mir angeschaut wie ich es damals gemacht habe. Letztlich habe ich das Synchronize aus dem Thread raus geschmissen und von außen direkt auf die Variablen zugegriffen. So wie man es bei einem Thread ja wohl eher nicht machen soll. Oder gelten in einer DLL andere Regeln?
D.h. mir fehlt eigentlich immer noch der korrekte Weg wie ich in einem Thread einen Wert veröffentliche und und ihn dann als Callback an die EXE zurück gebe. |
AW: Synchronize blockiert Anwendung
Du kannst Synchronize problemlos in einer DLL nutzen, wenn du das OnIdle aus der Anwendung durchreichst...
Das habe ich bei uns z.B. in die Standardschnittstelle für DLLs direkt eingebaut. In der DLL rufst du dann einfach in der im OnIdle aufgerufenen exportierten Prozedur CheckSynchronize auf. Schon funktioniert Synchronize. |
AW: Synchronize blockiert Anwendung
Alles, wo "gleichzeitig" mehr als ein Thread auf eine Variable zugreifen kann, egal ob EXE oder DLL, muß abgesichert werden.
Die genannten Interlocked-/Atom-Funktionen arbeiten "atomar", dass heißt, dass die Operation nur in einem CPU-Schritt erledigt werden, wo auch andere Threads während dieser Zeit keinen Zugriff haben. Somit sind diese Operationen per se thread-safe, da nur Einer zur selben Zeit Zugriff hat. Alles Andere muß über Sperren (z.B. CriticalSections) oder über Synchronisationsfunktionen (wo alle Operationen in einen eintigen Thread verschoben werden und somit er der Einzige ist) abgesichert werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz