Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   OpenDialog Problem (https://www.delphipraxis.net/171747-opendialog-problem.html)

youuu 22. Nov 2012 19:20

OpenDialog Problem
 
Hi ich wähle so eine Datei aus (im Thread)

Delphi-Quellcode:
try
    CritSektion.Enter;
      if frm_Start.OpenDialog.Execute then
         frm_Start.UniDump.RestoreFromFile(frm_Start.OpenDialog.Filename);
    CritSektion.Leave;
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
Komischerweise öffnet sich aber Opendialog nicht und Delphi überspringt es einfach

Bernhard Geyer 22. Nov 2012 19:25

AW: OpenDialog Problem
 
Zitat:

Zitat von youuu (Beitrag 1192467)
Hi ich wähle so eine Datei aus (im Thread)

Geht nicht. Alles was mit Windows-Handle in der VCL zu tun hat muss im Hauptthread verwendet werden. Dein TOpendialog gehört dazu da er reichlich vom parent-Handle und globalen VCL-Objekten gebrauch macht.

Liest den überhaupt keiner die Texte, die die IDE bei neuen TThraed-Nachfahren in die neue Pas-Datei schreibt?

himitsu 22. Nov 2012 19:30

AW: OpenDialog Problem
 
Auch das ShowMessage gehört in den Haupt-/VCL-Thread rein.

Deine CS sichert ja nur diesen einen Aufruf ab, so daß man Diesen nur einmal gleichzeitig ausführen kann,
aber die VCL bekommt davon garnichts mit und wird demnach auch nicht gesperrt.


Und zum Thema Resourcen-Schutzlöcke solltest du dir dringend nochmal so Einiges anlesen.
Rate mal was passiert, wenn es zwischen Enter und Leave knallt (z.B. im RestoreFromFile) ... alles (diese CS) blockiert ... für immer.

youuu 22. Nov 2012 19:48

AW: OpenDialog Problem
 
Ah ok danke, dann bau ich das mal um

himitsu 22. Nov 2012 20:25

AW: OpenDialog Problem
 
Delphi-Quellcode:
...
TThread.Synchronize(nil, procedure
  begin
    try
      if frm_Start.OpenDialog.Execute then
        frm_Start.UniDump.RestoreFromFile(frm_Start.OpenDialog.Filename);
    except
      on E: Exception do
        ShowMessage(E.Message);
    end;
  end;
...



...
TThread.Synchronize(nil, procedure
  begin
    doit := if frm_Start.OpenDialog.Execute;
    filename := frm_Start.OpenDialog.Filename;
  end;
if doit then
  try
    RestoreFromFile(filename);
  except
    on E: Exception do
      TThread.Synchronize(nil, procedure
        begin
          ShowException(E, nil);
        end;
  end;
...

bzw. wenn der Code in einem TThread-Execute steht, dann direkt
Delphi-Quellcode:
Synchronize(procedure
  begin

  end;
Sowas sollte man nur für kurze Funktionen nutzen, aber dafür kann man, bei diesen anonymen Methoden, auch lokale Variablen übergeben.

sx2008 22. Nov 2012 23:48

AW: OpenDialog Problem
 
Bei Threads sollte man gedanklich einen ganz anderen Ansatz wählen.
Ein Thread ist wie ein Baby - sämtliches Spielzeug muss ihm von seiner Mama gegeben werden.
Ein Thread sollte selbst nie in die Verlegenheit kommen irgendwelche Daten zu holen.

Beispiel:
Ein Thread soll über eine serielle Schnittstelle kommunizieren.
Die Daten dazu (COMx, Baudrate, Parity,..) stehen in einer Ini-Datei.
Anstatt dass der Thread die Ini-Datei öffnet und die Daten ausliest, hat der Thread entsprechende Properties (Baudrate, usw) und der Hauptthread liest die Ini-Datei und füttert den Thread vor dem Start mit Daten.
Dann gehen wir noch einen Schritt weiter.
Der Thread benötigt die Parameter Baudrate, Parity, usw eigentlich gar nicht.
Was er wirklich braucht ist ein geöffnetes TSerialPort-Objekt.
Delphi-Quellcode:
TKommunikationsThread = Class(TThread)
private
  FSerialPort : TSerialPort;
public
  procedure Execute; override;
  // muss von Aussen übergeben werden
  property SerialPort:TSerialPort read FSerialPort write FSerialPort;
end;
Das TSerialPort kann auch als Parameter über den Konstruktor übergeben werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz