![]() |
Re: Fragen zu Threads: Prozedur als Thread ausführen
Hmmm... dann fällt mir nur noch eins ein:
- Wie sieht es mit FreeOnTerminate aus? Ist das beim Thread auf true, damit der sich am Ende freigibt? - Du erstellst den Thread direkt. Ich weis nicht, ob das Probleme macht, aber evtl. solltest du eine Variable im TfrmCheck definieren, der der Thread zugewiesen wird.
Delphi-Quellcode:
HashThread := mCheck_Thread.TMyThread.Create(false);
|
Re: Fragen zu Threads: Prozedur als Thread ausführen
Hallo Whissi,
also ohne deinen Quellcode zu sehen, kann man schlecht sagen wo der Fehler liegt. Ich weiß auch nicht welche Aufgabe der Timer in deinem Projekt hat. Ich will dir aber anhand eines kleinen Beispiels zeigen, wie du einen Thread in deinem Projekt einsetzen kannst.
Delphi-Quellcode:
Beim Klick auf den Button wird dieser deaktiviert und ein neuer Thread wird erstellt.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } procedure OnThreadTerminate(Sender: TObject); public { Public-Deklarationen } end; TMyThread = class(TThread) public procedure Execute; override; end; var Form1: TForm1; implementation {$R *.dfm} {--------------------------------------------------------------------------------------------------} procedure TMyThread.Execute; begin Sleep(2000); end; {--------------------------------------------------------------------------------------------------} procedure TForm1.OnThreadTerminate(Sender: TObject); begin Screen.Cursor := crDefault; Button1.Enabled := True; end; {--------------------------------------------------------------------------------------------------} procedure TForm1.Button1Click(Sender: TObject); begin Screen.Cursor := crHourGlass; Button1.Enabled := False; with TMyThread.Create(True) do begin FreeOnTerminate := True; OnTerminate := OnThreadTerminate; Resume; end; end; {--------------------------------------------------------------------------------------------------} end. Beim erstellen wird der Constructor Create mit dem Wert True aufgerufen. So wird der Thread zwar erstellt aber noch nicht ausgeführt. Jetzt können einige Werte gesetzt werden. Zum Beispiel FreeOnTerminate. Damit du dich nicht selber um die Klassenspeicherverwaltung kümmern musst. Außerdem kannst du dort auch ein Ereignis setzten, das ausgeführt wird, wenn der Thread mit seiner Arbeit fertig ist. Erst der Aufruf von Resume führt dann den Thread aus. Ist der Thread beendet, wird das Ereignis OnThreadTerminate aufgerufen und der Button wird wieder aktiviert. |
Re: Fragen zu Threads: Prozedur als Thread ausführen
Hallo,
vielen Dank!!! Nach etwas herumspielen mit deinem Code-Beispiel konnte ich es 1:1 auf mein Projekt übertragen und habe es sogar verstanden (hoffe ich zumindest *G*). Jedenfalls macht das, was das Programm macht, Sinn ;-) Danke noch einmal! |
Re: Fragen zu Threads: Prozedur als Thread ausführen
ARGHS!
Das war wohl doch zu Vorschnell. In meinem Test-Projekt hat's soweit geklappt. Dort habe ich eben eine globale Variable im Wert verändert sowie Objekte des Formulars sichtbar/unsichtbar gemacht. In dem richtigen Projekt, bekomme ich nun Zugriffsverletzungen. Dabei habe ich deinen Code 1:1 reinkopiert. |
Re: Fragen zu Threads: Prozedur als Thread ausführen
Update:
Ich kann die Zugriffsverletzung nun klar festlegen: Ich lass in dem Thread der Variable "HASH", welche sich auf dem Formular "frmCheck" befindet, die ermittelte MD5-Hash übergeben. Beim Schreiben in diese Variable, steigt er aus. Dies ist mir jedoch unerklärlich, da ich mit der Variable zur Zeit weiter nichts mache - es sollte also kein Zugriff von anderen Forms auf die Variable existieren. Imho muss ich hier nun synchronisieren, nur wie bzw. womit? |
Re: Fragen zu Threads: Prozedur als Thread ausführen
Zitat:
Beispiel VCL Komponenten und Threads: (brauchst einen Button (Button1) und ein Textfeld (Edit1).
Delphi-Quellcode:
Ein Beispiel wenn du mehrere Threads hast, die die selbe Variable zum Lesen und Schreiben benutzen:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; TMyThread = class(TThread) private FEdit: TEdit; FHash: String; procedure Sync; protected procedure Execute; override; public constructor Create(Edit: TEdit; Hash: String); end; var Form1: TForm1; implementation {$R *.dfm} {--------------------------------------------------------------------------------------------------} constructor TMyThread.Create(Edit: TEdit; Hash: String); begin inherited Create(True); FEdit := Edit; FHash := Hash; end; {--------------------------------------------------------------------------------------------------} procedure TMyThread.Sync; begin FEdit.Text := FHash; end; {--------------------------------------------------------------------------------------------------} procedure TMyThread.Execute; begin Synchronize(Sync); end; {--------------------------------------------------------------------------------------------------} procedure TForm1.Button1Click(Sender: TObject); begin with TMyThread.Create(Edit1, 'ABC123') do begin FreeOnTerminate := True; Resume; end; end; {--------------------------------------------------------------------------------------------------} end.
Delphi-Quellcode:
Das Programm hat eigentlich keinen Auftrag, es soll dir nur zeigen wie du die Delphi Komponente TMultiReadExclusiveWriteSynchronizer einsetzen kannst.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) private { Private-Deklarationen } public { Public-Deklarationen } end; TReadThread = class(TThread) protected procedure Execute; override; end; TWriteThread = class(TThread) protected procedure Execute; override; end; var Form1: TForm1; implementation {$R *.dfm} var Safe: TMultiReadExclusiveWriteSynchronizer; procedure TReadThread.Execute; begin with Safe do begin BeginRead; // hier kannst du sicher von deiner Variablen lesen EndRead; end; end; procedure TWriteThread.Execute; begin with Safe do begin BeginWrite; // hier kannst du sicher in deine Variablen schreiben EndWrite; end; end; initialization Safe := TMultiReadExclusiveWriteSynchronizer.Create; finalization if Assigned(Safe) then Safe.Free; end. Beim Lesen: BeginRead, EndRead Beim Schreiben: BeginWrite, EndWrite Der Fehler der bei dir Auftritt, hat aber wohl einen anderen Grund. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:18 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-2025 by Thomas Breitkreuz