Autor |
Beitrag |
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: Mo 20.11.17 21:45
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
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 Christian S.: Delphi-Tags hinzugefügt
|
|
Symbroson
Beiträge: 382
Erhaltene Danke: 67
Raspbian, Ubuntu, Win10
C, C++, Python, JavaScript, Lazarus, Delphi7, Casio Basic
|
Verfasst: Mo 20.11.17 21:56
Delphi-Code Bereich (ohne die Leerzeichen)
[ delphi ] {code} [ / delphi ]
edit: post löschbar
_________________ most good programmers do programming not because they expect to get paid or get adulation by the public, but because it's fun to program. (Linus Torvalds)
Zuletzt bearbeitet von Symbroson am Di 21.11.17 13:09, insgesamt 1-mal bearbeitet
|
|
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: Di 21.11.17 11:52
|
|
TiGü
Hält's aus hier
Beiträge: 9
Erhaltene Danke: 1
|
Verfasst: Di 21.11.17 12:02
Ist ja wohl nicht dein Ernst?
www.delphipraxis.net...item-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?
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 21.11.17 12:10
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: 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 Christian 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?
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 21.11.17 13:15
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 21.11.17 13:48
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 21.11.17 14:16
Lenovo23456 hat folgendes geschrieben : | 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
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 21.11.17 16:07
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: 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
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 21.11.17 16:51
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Lenovo23456
Hält's aus hier
Beiträge: 14
|
Verfasst: Mi 22.11.17 09:29
Ich hätte es jetzt mal so
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
public
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ü
Hält's aus hier
Beiträge: 9
Erhaltene Danke: 1
|
Verfasst: Mi 22.11.17 09:53
Lenovo23456 hat folgendes geschrieben : | 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(0) as 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.
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
Hält's aus hier
Beiträge: 14
|
Verfasst: 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 Christian S.: Beiträge zusammengefasstUnd 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
Beiträge: 285
Erhaltene Danke: 33
DX10 Berlin Professional
|
Verfasst: Mi 22.11.17 10:37
Moin...
@Frühlingsrolle:
Ich muß mal TiGü in Schutz nehmen. 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 , 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!
|
|
TiGü
Hält's aus hier
Beiträge: 9
Erhaltene Danke: 1
|
Verfasst: Mi 22.11.17 10:38
Lenovo23456 hat folgendes geschrieben : |
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:
Frü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; |
|
|