Entwickler-Ecke

Sonstiges (Delphi) - TCollection & TCollectionitem


Lenovo23456 - Mo 20.11.17 21:45
Titel: TCollection & TCollectionitem
Hi, ich würde gerne eine TCollection erstellen und die darin enthaltenen TCollectionItems steuern. Das einfügen klappt, nur wie kann ich diese dann steuern?

Hier mal der Code


Delphi-Quelltext
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:
unit Unit7;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.ExtCtrls;
 
type
  TForm7 = class(TForm)
    Start: TButton;
    Button3: TButton;
    ListBox1: TListBox;
    Label1: TLabel;
    Memo1: TMemo;
    procedure StartClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
 
   end;
 
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  public
    constructor Create;
  end;
 
  TThreadItem = class(TCollectionItem)
  private
  public
    FThreadItem: TMyThread;
    constructor Create(ACollection: TCollection); override;
  published
  end;
 
  TThreadlist = class(TCollection)
  private
   procedure SetItems(Index: integer; AValue: TThreadItem);
  public
    constructor Create;
    function GetItems(Index: integer): TThreadItem;
    function AddEx: TThreadItem;
    property Items[Index: integer]: TThreadItem read GetItems write SetItems; default;
  end;
 
var
  Thread1: TMyThread;
  Form7: TForm7;
  ID: integer;
  ThreadL: TThreadlist;
 
implementation
 
{$R *.dfm}
 
constructor TThreadItem.Create(ACollection: TCollection);
begin
  inherited Create(ACollection);
  FThreadItem := TMyThread.Create;
 
end;
 
constructor TThreadlist.Create;
begin
  inherited Create(TThreadItem);
end;
 
function TThreadlist.GetItems(Index: integer): TThreadItem;
var
  i: integer;
begin
  result := TThreadItem(inherited Items[index]);
end;
 
procedure TThreadlist.SetItems(Index: integer; AValue: TThreadItem);
begin
  Items[Index].Assign(AValue);
end;
 
function TThreadlist.AddEx: TThreadItem;
begin
  result := inherited Add as TThreadItem;
end;
 
procedure TMyThread.Execute;
var
  ProgID: integer;
begin
  while not Terminated do
  begin
    sleep(100);
 
    Form7.Memo1.Lines.Add('Thread Nr. 0 ' + DateTimeToStr(Now) + ' Uhr');
 
  end;
end;
 
procedure TForm7.StartClick(Sender: TObject);
var
  Thread1: TMyThread;
  List: TThreadlist;
begin
 
  List.GetItems(0);
 
end;
 
constructor TMyThread.Create;
begin
  inherited Create(True);
end;
 
procedure TForm7.FormCreate(Sender: TObject);
var
  i: integer;
  Thread: TMyThread;
begin
  ThreadL := TThreadlist.Create;
  for i := 0 to 5 do
  begin
    ThreadL.AddEx;
  end;
  for i := 0 to 5 do
  begin
    if Assigned(ThreadL) then
      ListBox1.Items.AddObject('Thread Nr. ' + InTtoStr(i),
        TObject(ThreadL.GetItems(0)));
 
  end;
  ShowMessage(InTtoStr(ThreadL.count));
end;
 
end.



Sorry irgendwie hat das mit den Delphi Tags nicht geklappt, oder wie mache ich denn das?

Dankeschön
    
 

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


Symbroson - Mo 20.11.17 21:56

Delphi-Code Bereich (ohne die Leerzeichen)

[ delphi ] {code} [ / delphi ]

edit: post löschbar


Lenovo23456 - Di 21.11.17 11:52

Weiß keiner was ?


TiGü - Di 21.11.17 12:02

Ist ja wohl nicht dein Ernst? :shock:
http://www.delphipraxis.net/194306-tcollection-tcollectionitem-tutorial-9.html

Wir mühen uns da über 9 Seiten lang ab und es fehlt immer noch an den grundlegendsten Sachen wie Synchronize im Thread-Execute.
Nur weil dir in der Delphi-Praxis keiner die Lösung komplett hingeschrieben hat, versuchst du das jetzt hier?


Delete - Di 21.11.17 12:10

- Nachträglich durch die Entwickler-Ecke gelöscht -


Lenovo23456 - Di 21.11.17 12:10

Naja was soll ich machen, zum Ziel bin ich nicht gekommen. Und Synchronize hat ja was mit Threads zu tun, und ich will erstmal mit der TCollection arbeiten, also die execute ist erstmal unwichtig. Und wenn du schon auf delphi Praxis verweißt...ich soll Messages verwenden und nicht die Synchronize Methode

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst

@Frühlingsrolle...das ich wie in diesem Code z.b eine Thread starte.ich versteh nicht genau wie ich das anstelle. Ob ich über Tcollectionitem mit get und einem Index,den Thread hole darauf zugreife oder über TCollection und get?


Delete - Di 21.11.17 13:15

- Nachträglich durch die Entwickler-Ecke gelöscht -


Lenovo23456 - Di 21.11.17 13:25

Okay, ich möchte 6 Instanzen von TThread in einer TCollection speichern. Nur ich weiß nicht wie ich auf diese Instanzen dann zugreife. Ich denke das hinzufügen zur Collection hat geklappt. Ich hoffe du verstehst, was ich meine


Delete - Di 21.11.17 13:48

- Nachträglich durch die Entwickler-Ecke gelöscht -


Lenovo23456 - Di 21.11.17 14:03

Ja das verstehe ich, jeder Thread soll nur datum und Uhrzeit ausgeben. Nur das man halt sieht das er was macht. Wie im Code Beispiel Thread Nr 0. Und die Ausgabe soll auf einem Memo stattfinden. Ja ich weiß, nur das ist eine Übungsaufgabe und ich soll explizit mit einer TCollection arbeiten. Ich find leider einfach kein Beispiel, nach dem ich mich richten könnte


jaenicke - Di 21.11.17 14:16

user profile iconLenovo23456 hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
constructor TMyThread.Create;
begin
  inherited Create(True);
end;
Das True gibt an, dass du den Thread noch nicht starten möchtest...
Schreib da einfach mal False rein, dann laufen die Threads auch.

Wenn du Glück hast, gibt es auch erst einmal keine Fehler. Denn dass die Synchronisierung fehlt, wurde ja schon gesagt. Du darfst aus einem Thread nie direkt auf deine GUI zugreifen.


Lenovo23456 - Di 21.11.17 14:26

Danke, ja dann laufen sie sofort, aber ich soll sie durch einen Start Button starten und stopp Button wieder beenden. Ja ihr habt komplett recht mit Synchronize, nur ich wollte erst da weiter kommen, oder zumindest verstehen


Delete - Di 21.11.17 16:07

- Nachträglich durch die Entwickler-Ecke gelöscht -


Lenovo23456 - Di 21.11.17 16:19

Okay danke, das verstehe ich. Aber wie spreche ich meine einzelnen Threads in der Collection an. Über Tcollectionitem.get() und ein Index übergeben? Da kommt immer eine Fehlermeldung. Bei diesem Punkt, weiß ich nicht weiter


Delete - Di 21.11.17 16:51

- Nachträglich durch die Entwickler-Ecke gelöscht -


Lenovo23456 - Mi 22.11.17 09:29

Ich hätte es jetzt mal so


Delphi-Quelltext
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:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
 

interface

 

uses

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,

  System.Classes, Vcl.Graphics,

  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.ExtCtrls;

 

type

  TForm7 = class(TForm)

    Start: TButton;

    Button3: TButton;

    ListBox1: TListBox;

    Label1: TLabel;

    Memo1: TMemo;

    procedure StartClick(Sender: TObject);

    procedure FormCreate(Sender: TObject);

 

  private

    { Private-Deklarationen }

  public

    { Public-Deklarationen }

  end;

 

  TMyThread = class(TThread)

  protected

    procedure Execute; override;

  public

    constructor Create;

    procedure start(Thread:TMyThread);

  end;

 

  TThreadItem = class(TCollectionItem)

  private

  public

 

    FThreadItem: TMyThread;

    constructor Create(ACollection: TCollection); override;

    function getitem(index:integer):TThreadItem;

  published

  end;

 

  TThreadlist = class(TCollection)

  private

 

    procedure SetItems(Index: integer; AValue: TThreadItem);

  public

    constructor Create;

    function GetItems(Index: integer): TThreadItem;

    function AddEx: TThreadItem;

    property Items[Index: integer]: TThreadItem read GetItems

      write SetItems; default;

  end;

 

var

  Thread1: TMyThread;

  Form7: TForm7;

  ID: integer;

  ThreadL: TThreadlist;

 

implementation

 

{$R *.dfm}

 

procedure TMyThread.start(Thread: TMyThread);

begin

 

  Thread.Resume;

 

end;

 

 

function TThreaditem.getitem(index: Integer):TThreaditem;

var

d:TThreaditem;

h:TMyThread;

begin

 

d.SetIndex(0);

 

end;

 

constructor TThreadItem.Create(ACollection: TCollection);

begin

  inherited Create(ACollection);

  FThreadItem := TMyThread.Create;

 

end;

 

constructor TThreadlist.Create;

begin

  inherited Create(TThreadItem);

end;

 

function TThreadlist.GetItems(Index: integer): TThreadItem;

var

  i: integer;

begin

  result := TThreadItem(inherited Items[index]);

end;

 

procedure TThreadlist.SetItems(Index: integer; AValue: TThreadItem);

var

  T: TMyThread;

begin

  Items[Index].Assign(AValue);

end;

 

function TThreadlist.AddEx: TThreadItem;

begin

  result := inherited Add as TThreadItem;

end;

 

procedure TMyThread.Execute;

var

  ProgID: integer;

begin

  while not Terminated do

  begin

    sleep(100);

 

    Form7.Memo1.Lines.Add('Thread Nr. 0 ' + DateTimeToStr(Now) + ' Uhr');

 

  end;

end;

 

procedure TForm7.StartClick(Sender: TObject);

var

  Thread1: TMyThread;

  List: TThreadlist;

  h:TThreadItem;

begin

    Thread1:=TMyThread(ThreadL.GetItems(0));

    Thread1.Start(Thread1) ;

 

end;

 

constructor TMyThread.Create;

begin

  inherited Create(True);

end;

 

procedure TForm7.FormCreate(Sender: TObject);

var

  i: integer;

  Thread: TMyThread;

  d:TThreadItem;

begin

  ThreadL := TThreadlist.Create;

  for i := 0 to 5 do

  begin

    ThreadL.AddEx;

  end;

  for i := 0 to 5 do

  begin

    if Assigned(ThreadL) then

     ListBox1.Items.AddObject('Thread Nr. ' + InTtoStr(i),

        TObject(ThreadL.GetItems(0)));

 

  end;

  ShowMessage(InTtoStr(ThreadL.count));

end;

 

end.


Bei Thread.Resume kommt der Fehler " Thread Fehler: Das Handle ist ungültig "


TiGü - Mi 22.11.17 09:53

user profile iconLenovo23456 hat folgendes geschrieben Zum zitierten Posting springen:
Ich hätte es jetzt mal so


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm7.StartClick(Sender: TObject);
var
  Thread1: TMyThread;
  List: TThreadlist;
  h:TThreadItem;
begin
    Thread1:=TMyThread(ThreadL.GetItems(0));
    Thread1.Start(Thread1) ;
end;


Bei Thread.Resume kommt der Fehler " Thread Fehler: Das Handle ist ungültig "


Na, überlege nochmal haarscharf, ob das, was du per ThreadL.GetItems(0) holst, wirklich von Typ TMyThread ist.
Schreibe statt den harten Typecast doch mal folgendes:
Thread1 := ThreadL.GetItems(0as TMyThread;,
und lass dich mal überraschen, was dir für ein Laufzeitfehler entgegen schlägt.

Das exakt gleiche Probleme hattest du am 16.11.2017 auch.
http://www.delphipraxis.net/1386421-post82.html
Bitte erinnere dich an die darauf folgenden Beiträge.

@Frühlingsrolle: Ich sehe nicht wo mein Ton unangemessen war.
Vielleicht gibst du dir den neun Seiten langen DP-Thread mal in Ruhe.
Da haben mehrere Leute - u.a. auch ich - sich über Wochen lang ein Bein ausgerissen.
Leider ohne Erfolg. In Anbetracht dessen, verstehst du vielleicht meinen entsetzt-ungläubigen Ton.
Jetzt versucht er es hier...in der wagen Hoffnung, dass endlich jemand die komplette Lösung postet.


Lenovo23456 - Mi 22.11.17 10:13

Da du merkst das ich noch nicht weiter bin, ich versteh es nicht, und ich hab keine Ahnung wie ich es machen soll. Und ich hab hier nachgefragt war, weil ich mir nicht mehr anhören wollte wie schlecht ich bin.

PS: Ob ich die Aufgabe beende oder nicht interessiert keinen, deswegen brauch ich keine Lösung..ich will es nur kapieren.

Moderiert von user profile iconChristian S.: Beiträge zusammengefasst

Und ich geh sehr stark davon aus das kein Thread zurückkommt, sonder ein Tcollectionitem..nur ich verstehe nicht wie ich auf diesen Thread dann zugreife


haentschman - Mi 22.11.17 10:37

Moin... 8)
@Frühlingsrolle:
Ich muß mal TiGü in Schutz nehmen. :P Ich habe mich auch mit an dem DP Thread beteiligt. Mein Gefühl war ähnlich von TiGü. :(

@Lenovo23456
Wie auch aus dem DP Thread zu sehen ist, ist die Aufgabenstellung für deine Kenntnisse, im Moment noch :zwinker:, zu viel.
Mein Vorschlag:
Die Aufgabenstellung in Teilprobleme aufteilen und die Teilprobleme in Testprogrammen lösen. Diese Erkenntnisse dann in das Projekt einarbeiten.
1. TCollection (MeineKlasse)
2. TObjectList<MeineKlasse>
3. TThread
4. Synchronize
5. Messages
6. TObjectList<TThread> (alternativ)
...usw.

Für die einzelnen Probleme seperate Threads aufmachen.

...ich gebe das noch nicht auf. Aber du mußt dich auch an die Hinweise / Tipps exakt halten! :zustimm:


TiGü - Mi 22.11.17 10:38

user profile iconLenovo23456 hat folgendes geschrieben Zum zitierten Posting springen:

PS: Ob ich die Aufgabe beende oder nicht interessiert keinen, deswegen brauch ich keine Lösung..ich will es nur kapieren.

Und ich geh sehr stark davon aus das kein Thread zurückkommt, sonder ein Tcollectionitem..nur ich verstehe nicht wie ich auf diesen Thread dann zugreife

Gut, das ist ja soweit löblich.

Um ganz bei deinen jetzigen Quelltext zu bleiben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm7.StartClick(Sender: TObject);
var
  Thread1: TMyThread;
  h: TThreadItem;
begin
  h := ThreadL.GetItems(0);
  Thread1 := h.FThreadItem;
  Thread1.Resume;
end;


Die Delphi-IDE (IDE = Entwicklungsumgebung) bietet eine sogenannte Codevervollständigung an.
Wenn du bspw. in der Methode h. schreibst und mit den Cursor hinter den Punkt bleibst und dann Strg+Leertaste drückst, dann erscheint eine kleine Liste, die die öffentlichen Properties, Variablen und Methoden der jeweiligen Variablen aufzeigt.
Kennst du das?

Oben genannter Quelltext funktioniert so weit.
Was die asiatische Vorspeise aber eigentlich meinte war folgendes:

user profile iconFrühlingsrolle hat folgendes geschrieben:
Dann stell' in deiner TThreadItem-Klasse entsprechende .Start() und .Stop() Methoden auf. Darin rufst du, je nachdem, FThreadItem.Resume() oder FThreadItem.Suspend() auf.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm7.StartClick(Sender: TObject);
var
  Thread1: TMyThread;
  h: TThreadItem;
begin
  h := ThreadL.GetItems(0);
  h.Start;
end;

procedure TThreadItem.Start;
begin
  if Assigned(FThreaditem) and FThreadItem.Suspended then
  begin
    FThreadItem.Resume;
  end;
end;


Lenovo23456 - Mi 22.11.17 11:13

Okay vielen vielen Dank. Also wenn ich das richtig verstehe, macht man das so weil....

Ich habe FThreaditem in meiner Tcollectionitem Klasse als einen Typ von TMyThread deklariert. Dann im Constructor von TThreaditem habe ich geschrieben FThreaditem:=TMyThread.create. Damit erstelle ich meine einzelnen Threads und weise sie FThreaditem zu. Dann erstelle ich eine Instanz von TThreaditem (h) mit der ich dann wieder auf FThreaditem zugreife und mit FThreaditem wieder auf meine einzelnen Threads.

Also ich habe jetzt 6 TCollectionItems in meiner TCollection vom Typ TMyThread gespeichert?

Hab ich das so einigermaßen verstanden ?


TiGü - Mi 22.11.17 12:18

user profile iconLenovo23456 hat folgendes geschrieben Zum zitierten Posting springen:
Also ich habe jetzt 6 TCollectionItems in meiner TCollection vom Typ TMyThread gespeichert?

Hab ich das so einigermaßen verstanden ?


Ja.
Du hast 1 x TThreadlist mit 6 x TThreadItems mit je 1 x TMyThread.

Analoges Beispiel: Ein Einkaufswagen mit sechs Tüten in denen je ein Brot liegt.

Wieviele Brote hast du insgesamt?


Lenovo23456 - Mi 22.11.17 17:10

Oke, dann versteh ich es jetzt soweit. Vielen Dank .

Code wäre jetzt so


Delphi-Quelltext
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:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
unit Unit7;

 

interface

 

uses

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,

  System.Classes, Vcl.Graphics,

  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.ExtCtrls;

 

type

  TForm7 = class(TForm)

    Start: TButton;

    Button3: TButton;

    ListBox1: TListBox;

    Label1: TLabel;

    Memo1: TMemo;

    procedure StartClick(Sender: TObject);

    procedure FormCreate(Sender: TObject);

    procedure ListBox1Click(Sender: TObject);

    procedure Button3Click(Sender: TObject);

 

  private

    { Private-Deklarationen }

  public

    { Public-Deklarationen }

  end;

 

  TMyThread = class(TThread)

  protected

    procedure Execute; override;

  public

    constructor Create;

 

  end;

 

  TThreadItem = class(TCollectionItem)

  private

  public

 

    FThreadItem: TMyThread;

    constructor Create(ACollection: TCollection); override;

    procedure Start;

    procedure Stopp;

  published

  end;

 

  TThreadlist = class(TCollection)

  private

 

    procedure SetItems(Index: integer; AValue: TThreadItem);

  public

    constructor Create;

    function GetItems(Index: integer): TThreadItem;

    function AddEx: TThreadItem;

    property Items[Index: integer]: TThreadItem read GetItems

      write SetItems; default;

  end;

 

var

  Form7: TForm7;

  ID: integer;

  ThreadL: TThreadlist;

 

implementation

 

{$R *.dfm}

 

constructor TMyThread.Create;

begin

  inherited Create(True);

end;

 

constructor TThreadItem.Create(ACollection: TCollection);

begin

  inherited Create(ACollection);

  FThreadItem := TMyThread.Create;

 

end;

 

constructor TThreadlist.Create;

begin

  inherited Create(TThreadItem);

end;

 

procedure TThreadItem.Start;

begin

 

  FThreadItem.Resume;

 

end;

 

procedure TThreadItem.Stopp;

begin

  FThreadItem.Suspend;

end;

 

function TThreadlist.GetItems(Index: integer): TThreadItem;

begin

  result := TThreadItem(inherited Items[index]);

end;

 

procedure TThreadlist.SetItems(Index: integer; AValue: TThreadItem);

var

  T: TMyThread;

begin

  Items[Index].Assign(AValue);

end;

 

function TThreadlist.AddEx: TThreadItem;

begin

  result := inherited Add as TThreadItem;

end;

 

procedure TMyThread.Execute;

var

  ProgID: integer;

begin

  ProgID := ID;

  while not Terminated do

  begin

    sleep(100);

 

    Form7.Memo1.Lines.Add('Thread Nr. ' + IntToStr(ProgID) + ' ' +

      DateTimeToStr(Now) + ' Uhr');

 

  end;

end;

 

procedure TForm7.ListBox1Click(Sender: TObject);

begin

  ID := integer(ListBox1.Items.Objects[ListBox1.ItemIndex])

end;

 

procedure TForm7.FormCreate(Sender: TObject);

var

  i: integer;

begin

  ThreadL := TThreadlist.Create;

  for i := 0 to 5 do

  begin

    ThreadL.AddEx;

  end;

  for i := 0 to 5 do

  begin

    if Assigned(ThreadL) then

      ListBox1.Items.AddObject('Thread Nr. ' + IntToStr(i), TObject(i));

 

  end;

  ShowMessage(IntToStr(ThreadL.count));

end;

 

procedure TForm7.StartClick(Sender: TObject);

var

  Thread: TMyThread;

  StartItem: TThreadItem;

  StartID: integer;

begin

  StartID := ID;

 

  StartItem := ThreadL.GetItems(StartID);

  StartItem.Start;

 

end;

 

procedure TForm7.Button3Click(Sender: TObject);

var

  StartID: integer;

  StartItem: TThreadItem;

  Thread: TMyThread;

begin

  StartID := ID;

 

  StartItem := ThreadL.GetItems(StartID);

  StartItem.Stopp;

 

end;

 

end.


Dann beschäftige ich mich jetzt mal mit Synchronize und Messages


Delete - Mi 22.11.17 20:30

- Nachträglich durch die Entwickler-Ecke gelöscht -


haentschman - Do 23.11.17 08:15

Moin... 8)
Zitat:
...aber Hinweise wie die Logik von der GUI zu trennen, sind nicht gefallen. Oder warum wird noch immer in der Execute() Methode die Form7 und sonstiges aufgerufen.

Doch...siehe meinen Beitrag. Nur wurden die Hinweise nicht umgesetzt. :roll:
Zitat:

Der Zugriff auf GUI Elemente aus dem Thread heraus, ist keine gute Idee!
Besser:
Ein Event aus dem Thread mit Synchronize.

http://www.delphipraxis.net/1386197-post54.html


jaenicke - Do 23.11.17 10:13

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Oder warum wird noch immer in der Execute() Methode die Form7 und sonstiges aufgerufen.
Siehe oben:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wenn du Glück hast, gibt es auch erst einmal keine Fehler. Denn dass die Synchronisierung fehlt, wurde ja schon gesagt. Du darfst aus einem Thread nie direkt auf deine GUI zugreifen.


TiGü - Do 23.11.17 10:44

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Wenn man es nicht schafft, einem weniger erfahrenen Teilnehmer in wenigen Beiträgen zu erklären wie es geht, dann erklärt man es nicht richtig.

Der weniger erfahrene Teilnehmer ist Informatikstudent im fortgeschrittenen Semester und bearbeitet als Werkstudent seit ANFANG November diese Aufgabe.
So ein bisschen Eigeninitiative und Grundverständnis muss man da voraussetzen.
Er ist kein 14 jähriger Schüler.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:

Hier geht es wieder weiter um unwesentliche Dinge wie Milch und Brot, aber Hinweise wie die Logik von der GUI zu trennen, sind nicht gefallen.
Oder warum wird noch immer in der Execute() Methode die Form7 und sonstiges aufgerufen.

Es ging nur um Brot als analoges Beispiel, nicht um Milch.
Hinweise die Logik von der GUI zu trennen sind zuhauf und mehrfach und mit Doku-Hinweisen in der DP nachzulesen.
Leider wurden fast alle Vorschläge und Hinweise nicht umgesetzt. Siehe dein Hinweis mit den Start- und Stop-Methoden am Item.
Der war eigentlich klar und eindeutig. Stattdessen wurde an die Thread-Klasse eine Start-Methode rangebastelt.
Der TE kann aber halt auch nicht konkret seine Fragen formulieren. Man muss ihm auch immer die Fehlermeldungen aus der Nase ziehen.


Christian S. - Do 23.11.17 10:52

Es wäre schön, wenn Ihr die Off-Topic-Diskussion dann hier beenden könntet ;-)