Autor Beitrag
N3tw124rd
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75


D5 Prof.
BeitragVerfasst: Do 15.12.05 11:19 
Hallo,

ich habe mir ein Objekt programmiert welches die Prozeduren Open und Close hat sowie eine public variable sInfo.
Bei Open wird ein Formular erzeugt welches 2 Labels besitzt das eine Label bekommt die Info Varaible zu gewiesen und das andere Label soll ein Flicker sein, welcher über ein Timer immer einen Schritt weiter geschaltet wird.
Das Open bekommt als Parameter noch ein self mit damit ich das Formular im Objekt erzeugen kann.
Das ganze sieht dann z.b. so aus

ausblenden Delphi-Quelltext
1:
2:
3:
4:
  oInfo.sInfo := 'Daten werden erzeugt';
  oInfo.Open(self);
  
  oInfo.Close;


Wenn ich nun zwischen dem Open und dem Close Datenbank abfragen mache und Berechnungen dann geht mein Flicker nicht :(
Wenn ich aber nach dem Open ein Formular aufrufe in dem die Berechnungen gemacht werden dann funktioniert der Flicker :)
Weiß jemand was ich da falsch mache mit dem Timer ??
Ich habe auch mal ein Breakpoint in den Timer gesetzt und er wird einfach nicht getriggert. :(

Vielen Dank schon mal
N3tw124rd

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt.
Stefan.Buchholtz
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 612

WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
BeitragVerfasst: Do 15.12.05 11:40 
Damit während einer längeren Berechnung Timer-Events ausgeführt werden, musst du während der Berechnung regelmässig Application.ProcessMessages; aufrufen. Der Timer läuft nicht in einem separaten Thread, sondern Windows versendet regelmässig WM_TIMER Messages an dein Programm. Wenn das Programm keine Messages verarbeitet, weil es gerade etwas anderes macht, wird das Timer-Event auch nie ausgelöst - genauso, wie Fenster nicht neugezeichnet werden und das Programm auch nicht auf Tastatureingaben oder Mausklicks reagiert.

Stefan

_________________
Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
N3tw124rd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75


D5 Prof.
BeitragVerfasst: Do 15.12.05 11:51 
Danke für deine schnelle Antwort aber das mit den Processesmessages habe ich schon versucht. Werde es aber noch einmal versuchen.
Gibt es noch eine andere Möglichkeit ??

Vielen Dank
N3tw124rd
wdbee
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Do 15.12.05 12:38 
Klar, du kannst separate Threads einsetzten. Dabei ist es aber wichtig, die Aufgaben sauber zu trennen:
Die VCL ist nicht threadsicher, d.h. Anzeigen (unter Nutzung von VCL-Objekten) dürfen nur vom "VCL-Thread" gemacht werden, also dem Hauptthread deiner Anwendung. Deshalb musst du die "Berechnungen" in einem separaten Thread machen (und ggf. anfallende Anzeigen dazu mit der Funktion Synchronize realisieren).
N3tw124rd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75


D5 Prof.
BeitragVerfasst: Do 15.12.05 12:48 
Ich habe mir einen Thread jetzt erzeugt mittels TThread

thr := TThread.Create(TRUE);

wie kann ich dem thr nun die Funktion zu weisen die er ausführen soll ??

Danke
N3tw124rd
wdbee
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 628
Erhaltene Danke: 1



BeitragVerfasst: Do 15.12.05 12:59 
Das Thema Threads ist nicht ganz einfach. Eine gute und weitgehend vollständige Darstellung des Themas findest du in Lucky's Tutorial.
www.michael-puff.de/...er/Delphi/Tutorials/
N3tw124rd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75


D5 Prof.
BeitragVerfasst: Do 15.12.05 13:18 
Habe mich dazu entschlossen die CreateThread Funktion zu verwenden...

Aber mein Compiler meldet hier

ThreadHandle:=CreateThread(NIL, 0, TFNThreadStartRoutine(@ThreadFunc), NIL, 0, ThreadID);

Variable Required

Der Rest wie das dann abläuft mit dem Thread ist mir klar.

Danke
N3tw124rd
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Do 15.12.05 13:27 
Also ich persönlich benutze eigentlich immer den Objekt Orientierten Ansatz mit TThread. Bin aber auch einfach zu Faul um mich um den Rest selber kümmern zu müssen. Warum auch. Existiert ja schon alles.

Aber zu deinem Problem. Die einzige Variable die dort Existiert ist die ThreadID. Wo hast du die denn Deklariert. Dabei muss es sich um eine Variable handeln. Bzw durch das @ bekommst du die Adress der Methode. Eigentlich sollte es genügen, wenn du das TypeCasting dort auch weglässt. Also nur @ThreadFunc

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
N3tw124rd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75


D5 Prof.
BeitragVerfasst: Do 15.12.05 14:51 
Also ich habe jetzt mal versucht das ganze abzuändern...

ausblenden Delphi-Quelltext
1:
  ThreadHandle:=CreateThread(NIL0, @ThreadFunc, pTmp, 0, ThreadID);					


pTmp ist NIL und ich bekomme wieder den Fehler Variable required.
ThreadID ist private in dem objekt deklariert welches den Thread erzeugt...
In der CreateThread hilfe von Delphi 2005 steht das der 4. Parameter (pTmp) ein Rückgabe wert ist. Aber selbst mit pTmp sagt er immer noch

Variable required

:(

Danke N3tw124rd

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt.
N3tw124rd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75


D5 Prof.
BeitragVerfasst: Do 15.12.05 18:10 
Also das mit dem Variable Required habe ich mit einem Codezeiger gelöst...
Das @ funktioniert nur bei variablen, auf jedenfall bei Delphi 2005.
Deshalb muß hier ein Codezeiger verwendet werden.
Ungefähr so

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
  TEventProc = Procedure of Object;

  oInfo = Object
    procEvent   : TEventProc;
    Procedure Open(aOwner : TComponent);
       .
       .
       .
  End;

Procedure oInfo.Open(aOwner : TComponent);
Begin
  .
  .
  .
  procEvent := ThreadEvent;
  ThreadHandle := CreateHandle(NIL0, @procEvent, NIL0, ThreadID);
  .
  .
  .
End;



Im Endeffekt hat es mir aber nicht geholfen, weil in dem Thread mein im Object erstelltes Formular nicht verfügbar ist und ich dann eine Access Violation bekomme :(
Naja aber ich habe gelernt wie man Threads erzeugt und sie verwendet.
Dafür schon mal ein Danke schön an alle die mir geholfen haben.

Gruß
N3tw124rd

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt.