AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Synchronize blockiert Anwendung

Ein Thema von norwegen60 · begonnen am 6. Dez 2017 · letzter Beitrag vom 6. Dez 2017
Antwort Antwort
norwegen60

Registriert seit: 23. Dez 2007
225 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 18:03
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:
library UV;

uses
  SysUtils,
  Windows,
  Classes,
  uProcessUv in 'uProcessUv.pas',
  uThreadUv in 'uThreadUv.pas';

{$R *.res}

exports
  SetCommandW;

end.
Der Prozesshandler
Delphi-Quellcode:
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.
Der Threadhandler
Delphi-Quellcode:
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.
und zuletzt der Aufruf
Delphi-Quellcode:
procedure SetCommandW; stdcall; external 'UV.dll';

procedure TForm6.Button1Click(Sender: TObject);
begin
  SetCommandW;
end;
Egal, ob ich an Synchronice etwas assigned habe oder nicht, hängt sich die Anwendung beim Aufruf von Synchronize(syncStatusEvent); auf

Kann mir jemand sagen was ich falsch mache.

Vielen Dank
Gerd
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
4.207 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 18:12
Guck mal, ich glaub ich kenne den Kerl:

Thread in DLLdll.html
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
33.489 Beiträge
 
Delphi XE3 Professional
 
#3

AW: Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 18:37
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 Thread in DLLdll.html
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
225 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 20:17
Guck mal, ich glaub ich kenne den Kerl:

Thread in DLLdll.html
Oh, Schitt, wie peinlich.
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.
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
225 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 20:52
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.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
6.580 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#6

AW: Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 22:04
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
33.489 Beiträge
 
Delphi XE3 Professional
 
#7

AW: Synchronize blockiert Anwendung

  Alt 6. Dez 2017, 22:11
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2017 by Daniel R. Wolf