-
Notifications
You must be signed in to change notification settings - Fork 1
/
bi_threadtimer.pas
160 lines (141 loc) · 3.72 KB
/
bi_threadtimer.pas
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
unit bi_threadtimer;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TThreadComponent = class;
TNestedThread = class(TThread)
OwnerThreadComponent: TThreadComponent;
procedure Execute; override;
procedure DoExecute;
end;
TThreadComponent = class(TComponent)
private
FEnabled: Boolean;
FOnExecute: TNotifyEvent;
FOnTerminate: TNotifyEvent;
FOnStart: TNotifyEvent;
FThreadPriority: TThreadPriority;
FNestedThread: TNestedThread;
FSleep: DWORD;
protected
procedure SetEnabled(Value: Boolean);
procedure SetOnExecute(Value: TNotifyEvent);
procedure SetThreadPriority(Value: TThreadPriority);
procedure Execute; dynamic;
procedure Terminate; dynamic;
procedure Start; dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default false;
property OnExecute: TNotifyEvent read FOnExecute write SetOnExecute;
property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
property OnStart: TNotifyEvent read FOnStart write FOnStart;
property Sleep: DWORD read FSleep write FSleep default 1;
property ThreadPriority: TThreadPriority read FThreadPriority write SetThreadPriority default tpNormal;
end;
function GetNestedThreadsMaxSleep(AOwner: TComponent): DWORD;
implementation
procedure TNestedThread.Execute;
begin
if (OwnerThreadComponent = nil) then
repeat
Sleep(10);
until (OwnerThreadComponent <> nil) or Terminated;
if not Terminated then
repeat
if not (csDestroying in OwnerThreadComponent.ComponentState) then
begin
SleepEx(OwnerThreadComponent.Sleep, false);
Synchronize(DoExecute);
end
else
Terminate
until Terminated;
end;
procedure TNestedThread.DoExecute;
begin
OwnerThreadComponent.Execute;
end;
constructor TThreadComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := false;
FThreadPriority := tpNormal;
FSleep := 1;
FNestedThread := TNestedThread.Create(false);
FNestedThread.OwnerThreadComponent := Self;
FNestedThread.Suspend;
end;
destructor TThreadComponent.Destroy;
begin
FNestedThread.Suspend;
if FEnabled then Terminate;
FNestedThread.Free;
inherited Destroy;
end;
procedure TThreadComponent.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
if FEnabled then
begin
Start;
FNestedThread.Resume
end
else
begin
FNestedThread.Suspend;
Terminate
end;
end;
end;
procedure TThreadComponent.SetOnExecute(Value: TNotifyEvent);
begin
FOnExecute := Value;
if FEnabled then
begin
FNestedThread.Suspend;
FNestedThread.Resume;
end;
end;
procedure TThreadComponent.SetThreadPriority(Value: TThreadPriority);
begin
if Value <> FThreadPriority then
begin
FThreadPriority := Value;
if FEnabled then
begin
FNestedThread.Suspend;
FNestedThread.Priority := FThreadPriority;
FNestedThread.Resume;
end;
end;
end;
procedure TThreadComponent.Execute;
begin
if Assigned(FOnExecute) then FOnExecute(Self);
end;
procedure TThreadComponent.Terminate;
begin
if Assigned(FOnTerminate) then FOnTerminate(Self);
end;
procedure TThreadComponent.Start;
begin
if Assigned(FOnStart) then FOnStart(Self);
end;
function GetNestedThreadsMaxSleep(AOwner: TComponent): DWORD;
var i: integer;
begin
result := 0;
for i := 0 to AOwner.ComponentCount - 1 do
begin
if (AOwner.Components[i] is TThreadComponent) then
if result < (AOwner.Components[i] as TThreadComponent).Sleep then
result := (AOwner.Components[i] as TThreadComponent).Sleep
end;
end;
end.