[Delphi] Thread geeft event aan programma

Pagina: 1
Acties:
  • 133 views sinds 30-01-2008
  • Reageer

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb een thread en die moet eigenlijk een event hebben die hij op een bepaald punt in de execute aanroept zodat het programma (die de thread heeft gestart) weet waar de thread is. Misschien een beetje vaag, maar zo moet het ongeveer verlopen:
- programma maakt en start thread (create, execute)
- thread begint (execute)
- thread geeft halverwege execute procedure een signaal aan programma (event?)
- thread gaat verder met execute
- thread geeft weer een signaal aan programma (event?)
- thread is klaar (terminate)
Weet iemand hoe ik dit nou doe, zodat de thread die events geeft aan het programma? Is dit uberhaupt mogelijk?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

In je thread een sendmessage doen, en die in de messagehandler van je mainthread weer opvissen lijkt me het meest praktish?

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op woensdag 10 oktober 2001 17:43 schreef Yarvieh het volgende:
In je thread een sendmessage doen, en die in de messagehandler van je mainthread weer opvissen lijkt me het meest praktish?
Is misschien een idee, maar kan het niet met events?

Ik heb verder weinig ervaring hiermee, dus misschien zeg ik wel iets heel doms. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Ik zou kiezen voor PostMessage, voordeel asynchroon, thread hoeft niet te wachten, lijkt me ook de meest logische oplossing.

Met een event moet het ook gewoon kunnen. Eventueel in een synchronize zetten.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op woensdag 10 oktober 2001 18:13 schreef DiFool het volgende:
Met een event moet het ook gewoon kunnen. Eventueel in een synchronize zetten.
Hoe dan precies?

Ik vond een event wel makkelijk, ook omdat ik gebruik maak van die OnTerminate event van een thread. Dus ik dacht dat ik zelf ook wel een event moet kunnen maken en die dan aaroepen op een bepaald punt in de thread.

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Oke code :)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
unit ThreadTest;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  WM_Test = WM_USER + 1;

type
  TMyThread = class(TThread)
  private
    FDestHandle: THandle;
    FSomeEvent: TNotifyEvent;
    procedure DoSyncEvent;
    procedure DoMessage;
    procedure DoEvent;
    procedure Wait;
  public
    procedure Execute; override;
    property SomeEvent: TNotifyEvent read FSomeEvent write FSomeEvent;
    property DestHandle: THandle read FDestHandle write FDestHandle;
  end;

  TForm1 = class(TForm)
    ListBox1: TListBox;
    btnStart: TButton;
    btnStop: TButton;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    FThread: TMyThread;
    procedure ThreadEvent(Sender: TObject);
    procedure ThreadDone(Sender: TObject);
    procedure CMTest(var Msg: TMessage); message WM_Test;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

{ TMyThread }

procedure TMyThread.DoEvent;
begin
  if Assigned(FSomeEvent) then FSomeEvent(Self);
end;

procedure TMyThread.DoMessage;
begin
  PostMessage(FDestHandle, WM_Test, 0, 0);
end;

procedure TMyThread.DoSyncEvent;
begin
  Synchronize(DoEvent);
end;

procedure TMyThread.Execute;
begin
  FreeOnTerminate := True;
  Priority := tpLower;
  while not Terminated do
  begin
    Wait;
    DoMessage;
    Wait;
    DoSyncEvent;
  end;
end;

procedure TMyThread.Wait;
begin
  WaitForSingleObject(Handle, 2000);
end;

{ TForm1 }

procedure TForm1.CMTest(var Msg: TMessage);
begin
  ListBox1.Items.Add('Post test');
end;

procedure TForm1.btnStartClick(Sender: TObject);
begin
  if Assigned(FThread) then Exit;
  FThread := TMyThread.Create(True);
  with FThread do
  begin
    DestHandle := Self.Handle;
    SomeEvent := ThreadEvent;
    OnTerminate := ThreadDone;
    Resume;
  end;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
  if Assigned(FThread) then FThread.Terminate;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if Assigned(FThread) then
  begin
    FThread.Terminate;
    FThread.WaitFor;
  end;
end;

procedure TForm1.ThreadEvent(Sender: TObject);
begin
  ListBox1.Items.Add('Event test');
end;

procedure TForm1.ThreadDone(Sender: TObject);
begin
  ListBox1.Items.Add('Thread done');
  FThread := nil;
end;

end.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Thanks, zal er morgen even naar kijken! :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 17:41 schreef jelmervos het volgende:
Weet iemand hoe ik dit nou doe, zodat de thread die events geeft aan het programma? Is dit uberhaupt mogelijk?
Ik snapte eerste even de term event niet binnen de context daar we het de afgelopen dagen hier erg veel over synchronization objects gehad hebben, maar je bedoelt denk ik gewoon een VCL event :)

En da's inderdaad geen probleem, gewoon een stel TNotifyEvents definieren en die binnen TThread::Synchronize calls aanroepen. Sla de help er maar ff op na hoe je het in Delphi precies maakt (in C++Builder kan ik het wel maar da's op dit gebied toch een stuk anders... iemand een __closure? :P )

Professionele website nodig?


Verwijderd

Je kan met threadevents een call back maken naar een procedure buiten je thread.. dit is super handig als je met threads werkt.. Je kan ook zelf een callback maken mbv een pointer in je contructor naar een externe procedure...

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Dus wat is nou precies het beste wat ik kan doen???

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Op donderdag 11 oktober 2001 10:33 schreef jelmervos het volgende:
Dus wat is nou precies het beste wat ik kan doen???
TNotifyEvents is het makkelijkste..

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 11 oktober 2001 10:42 schreef cartman3380 het volgende:

[..]

TNotifyEvents is het makkelijkste..
Voorbeeldje of URL met info hierover? Leer ik ook nog es wat. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Op donderdag 11 oktober 2001 10:44 schreef jelmervos het volgende:

[..]

Voorbeeldje of URL met info hierover? Leer ik ook nog es wat. :)
Ik ICQ je van het weekend wel wat..

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 11 oktober 2001 11:08 schreef cartman3380 het volgende:

[..]

Ik ICQ je van het weekend wel wat..
Had je al toegevoegd op ICQ, maar dus niet online.
Ik probeer nog wel ff wat tot het weekend. Google biedt ook altijd leuke dingen. :)

(Ik ben ook weer ff bij Wasp geweest).

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Op donderdag 11 oktober 2001 10:44 schreef jelmervos het volgende:

[..]

Voorbeeldje of URL met info hierover? Leer ik ook nog es wat. :)
Eh, heb je mijn voorbeeld wel bekeken?

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 11 oktober 2001 15:15 schreef DiFool het volgende:

[..]

Eh, heb je mijn voorbeeld wel bekeken?
Heb er al even naar gekeken, maar zal er vanavond beter naar kijken. Zit nu op school enzo, vandaar. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op donderdag 11 oktober 2001 15:15 schreef DiFool het volgende:

[..]

Eh, heb je mijn voorbeeld wel bekeken?
Ik heb er even naar gekeken, en ik moet zeggen dat het aardig werkt! Maar nu heb ik nog als probleem dat ik een waarde mee wil geven met die event. Is dit ook mogelijk?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Dat gaat ja, gebruik ipv TNotifyEvent iets anders bv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
type
  { Zo wordt TNotifyEvent gedef. in Classes
  TNotifyEvent = procedure(Sender: TObject) of object; }

  TIntegerEvent1 = procedure(Sender: TObject; const AInt: Integer)
    of object;

  { Integer kan nu veranderd worden door ontvanger van event }
  TIntegerEvent2 = procedure(Sender: TObject; var AInt: Integer)
    of object;

  { Sender hoeft niet doorgegeven te worden, maar is wel gebruikelijk }
  TIntegerEvent3 = procedure(const AInt: Integer) of object;

Als FSomeEvent nu van het type TIntegerEvent2 is dan zou je DoEvent kunnen veranderen in:
code:
1
2
3
4
5
6
7
8
procedure TMyThread.DoEvent;
var
  I: Integer;
begin
  I := ..
  if Assigned(FSomeEvent) then FSomeEvent(Self, I);
  DoeIetsMet(I);
end;

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Thanks, zal er vanavond zeker even naar kijken.

DiFool: heb jij toevallig ICQ/MSN???

"The shell stopped unexpectedly and Explorer.exe was restarted."

Pagina: 1