In einem Trehad ein Dialog auf rufen und wieder schließen ?
Ach Pluto. Vergiss einfach mal die extra Threads. Erstens kapierst du's scheint's nicht und zweitens brauchst du das nicht.pluto hat geschrieben:doch bei mir schon, weil ich pro Fenster z.b. ein Archiv Öffnen kann/möchte oder aber halt Dateien Verschieben, Kopieren und gleichzeitig ein Neues Archiv erstellen.
Extra Threads sollte man meiner Meinung nach nur dann verwenden, wenn man GENAU weiss wozu. In deinem Falle sind sie nicht nötig.
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
@pluto
Schließen des Formulars wäre eine Sache für TThread.OnTerminate. Das wird aufgerufen bevor der Thread endgültig geschlossen wird. Veränderungen am Formular gehen nur mit Synchronized und eventuell zusätzlich Suspended:= true(false). Bei Synchronized könntest du z.B. deine globalen Variablen setzen, soweit die vom Thread abhängen. Günstiger ist für sowas aber meist eine Struktur, die auch von TObject abstammen darf.
Schließen des Formulars wäre eine Sache für TThread.OnTerminate. Das wird aufgerufen bevor der Thread endgültig geschlossen wird. Veränderungen am Formular gehen nur mit Synchronized und eventuell zusätzlich Suspended:= true(false). Bei Synchronized könntest du z.B. deine globalen Variablen setzen, soweit die vom Thread abhängen. Günstiger ist für sowas aber meist eine Struktur, die auch von TObject abstammen darf.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
Du verstehst das falsch. Christian hat das nicht böse gemeint. Und Schnullerbacke's Anmerkung (welche wieder mal ziemlich unverständlich ist) bringt dich keinen Schritt weiter (ausser ihr zwei habt mittlerweile einen Spezialcode entwickelt um Erkenntnisse auszutauschen)
Es gibt einfach Sachen, die mit deiner "Hau-Ruck" Methode nicht zu erschliessen sind. Dazu gehören die TThreads, das musst du zuerst theoretisch verstehen, das hat dir Monta schon gesagt.
Aber wenn du mir glauben möchtest, dann vergiss die Threads. Du brauchst die nicht.
Es gibt einfach Sachen, die mit deiner "Hau-Ruck" Methode nicht zu erschliessen sind. Dazu gehören die TThreads, das musst du zuerst theoretisch verstehen, das hat dir Monta schon gesagt.
Aber wenn du mir glauben möchtest, dann vergiss die Threads. Du brauchst die nicht.
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Genau, ich will dich nur davor bewahren immer wieder auf die Schnauze zu fallen wenn ich mich mal so ausdrücken darf. Ausserdem ist es langsam wirklich nicht mehr schön das du dich nicht mit den Problemen die du hast auseinandersetzt sondern einfach immer hier postest wenn du ein Problem hast.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
ersten habe ich nicht sofort gepostet, ich habe lange nach Lösungen gesucht.
Wie ich es meistens machen:
wenn ich selbst keine Ideen mehr habe um ein Problem zu lösen, suche ich die Foren ab. Wenn ich da nichts finde Poste ich eine neue Frage.
Ich habe mir überlegt ob ich diese Frage nicht in einem anderen Forum stellen sollte bzw. hätte. Naja. ich habe mich selten eigentlich noch gar nicht mit Thread auseinander gesetzt.
Darum möchte ich dies tun. Es ist etwas neues.
und ich weiß eure sorge(n) zu schätzten. Vielen Dank dafür.
naja warum kann ich das schließen nicht im TThread.OnTerminate
rein packen ?
Aber ich bin davon überzeugt, das er noch nicht mal soweit kommt.
ich muss mir meine Methode nochmal genau ansehen. mal sehen.
Danke für eure Vorschläge ich werde sie der reihe nach "Prüfen" und umsetzten.
Wie ich es meistens machen:
wenn ich selbst keine Ideen mehr habe um ein Problem zu lösen, suche ich die Foren ab. Wenn ich da nichts finde Poste ich eine neue Frage.
Ich habe mir überlegt ob ich diese Frage nicht in einem anderen Forum stellen sollte bzw. hätte. Naja. ich habe mich selten eigentlich noch gar nicht mit Thread auseinander gesetzt.
Darum möchte ich dies tun. Es ist etwas neues.
und ich weiß eure sorge(n) zu schätzten. Vielen Dank dafür.
naja warum kann ich das schließen nicht im TThread.OnTerminate
rein packen ?
Aber ich bin davon überzeugt, das er noch nicht mal soweit kommt.
ich muss mir meine Methode nochmal genau ansehen. mal sehen.
Danke für eure Vorschläge ich werde sie der reihe nach "Prüfen" und umsetzten.
MFG
Michael Springwald
Michael Springwald
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Code: Alles auswählen
procedure TBackupThread.Execute;
const
READ_BYTES = 1;//2048;
var
S: TStringList;
M: TMemoryStream;
P: TProcess;
n: LongInt;
BytesRead: LongInt;
str,fz:String;
t:Boolean;
dir:TDir;
begin
Synchronize(@StopTimer);
// writeln('OK');
//MakeProgress('');
M := TMemoryStream.Create; BytesRead := 0;
s:=TStringlist.Create; P := TProcess.Create(nil);
P.CommandLine := '7za '+Para; P.Options := [poUsePipes];
P.Execute; t:=False;
str:=''; SetLength(fz,3); Synchronize(@lw.BeginUpdate);
if (dirlevel > 1) then begin
with lw.Items.Add do begin
dir:=TDir.Create;
dir.dir:='..';
dir.TempName:='';
caption:='[..]';
data:=dir;
end;
end;
Writeln('OK:001');
while P.Running do begin
M.SetSize(BytesRead + READ_BYTES);
n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
m.Read(fz[1],1);
if fz[1] <> #10 then
str:=str+fz[1]
else begin
if Pos('Path',str) > 0 then t:=True;
if str = '' then begin
t:=False;
// Writeln(s.Text);
// writeln('.');
AddLV(lw,s,dirLevel);
s.Clear;
end;
if t = True then s.add(str);
str:='';
end;
if n > 0 then Inc(BytesRead, n) else Break;
// if BytesRead >=9000 then break;
end;
Synchronize(@lw.EndUpdate);
Writeln('OK:002|',m.size);
Synchronize(@lw.BeginUpdate);
if m.size = 0 then begin
repeat
M.SetSize(BytesRead + READ_BYTES);
n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
m.Read(fz[1],1);
if fz[1] <> #10 then
str:=str+fz[1]
else begin
if Pos('Path',str) > 0 then t:=True;
if str = '' then begin
t:=False;
AddLV(lw,s,dirLevel);
s.Clear;
end;
if t = True then s.add(str);
str:='';
end;
if n > 0 then Inc(BytesRead, n) else Break;
until n <= 0;
end;
Synchronize(@lw.EndUpdate);
Writeln('OK:003');
M.SetSize(BytesRead);
p.Free; m.Free;
writeln('O11K');
Synchronize(@Progress);
end;
@Schnullerbacke
ich kann mit Synchronize leider keine Variablen Synchronizen genauso wenig einfache unit Prozeduren.
MFG
Michael Springwald
Michael Springwald
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Du kannst mit Synchronize alles syncronisieren du musst es nur verstanden haben. Und deine Problemlösungsfindung mag zwar funktionieren nur löst nicht du die Probleme sondern immer ein anderer für dich. Du solltest als Programmierer deiner "Projekte" am besten immer die Leute angeben von denen du die Lösungen hast. Denn viel hast du ja daran nicht Programmiert.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
Nix freu.pluto hat geschrieben: Aber es geht jetzt *Freu*
Du hast immer noch unsynchronisierte Teile da drin:
z.B. lw.Items.Add. wahrscheinlich auch AddLV(..)
Aber so macht man's einfach nicht. Lass den Thread einfache Resultate liefern und tu nicht zuviel mit den visuellen Komponenten da rumwurschteln. Das muss auf die Dauer in die Hose gehen.
Oder noch viel besser: VERGISS DIE THREADS!!!!!!!!!!!!!!
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
ich habe versucht AddLV synchronisierte das wollte der Kompiler nicht.
Liegt daran das AddLV keine Methode ist sondern einfach nur eine Procedure.
Du meinst ich sollte alles synchronisiern was ich aufrufe ?
Dann mal eine Frage: du sagt das ich da nicht viel mit viusellen Komponenten "rum wurschteln" soll. Aber mein Ziel war es: eine beliebige ListView mit Einträgen zu fühlen. mehr nicht. und mehr macht dieser Thread auch nicht.
ich werde gleich noch mal versuchen ob ich da noch was Verbessern kann.
Das Problem ist auch das AddLV Parameter erwartet. ich glaube das geht nicht so einfach.
Nur weil ich mit Thread Probleme habe soll ich sie vergessen Theo ?
ich finde das ist kein Grund. Jetzt habe ich eine Passende Aufgabe für Thread und werde sie auch dort einsetzen.
Bei lw.Items.Add.kann ich es noch versuchen. Das Stimmt.
Liegt daran das AddLV keine Methode ist sondern einfach nur eine Procedure.
Du meinst ich sollte alles synchronisiern was ich aufrufe ?
Dann mal eine Frage: du sagt das ich da nicht viel mit viusellen Komponenten "rum wurschteln" soll. Aber mein Ziel war es: eine beliebige ListView mit Einträgen zu fühlen. mehr nicht. und mehr macht dieser Thread auch nicht.
ich werde gleich noch mal versuchen ob ich da noch was Verbessern kann.
Das Problem ist auch das AddLV Parameter erwartet. ich glaube das geht nicht so einfach.
Nur weil ich mit Thread Probleme habe soll ich sie vergessen Theo ?
ich finde das ist kein Grund. Jetzt habe ich eine Passende Aufgabe für Thread und werde sie auch dort einsetzen.
Bei lw.Items.Add.kann ich es noch versuchen. Das Stimmt.
MFG
Michael Springwald
Michael Springwald
Vor allem kannst du sie vergessen, weil du sie für diese Aufgabe nicht benötigst.pluto hat geschrieben: Nur weil ich mit Thread Probleme habe soll ich sie vergessen Theo ?
ich finde das ist kein Grund. Jetzt habe ich eine Passende Aufgabe für Thread und werde sie auch dort einsetzen.
Aber das kann ich wohl noch hundert mal sagen. Es interessiert dich ja eh nicht.
-
- Beiträge: 1187
- Registriert: Mi 13. Dez 2006, 10:58
- OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
- CPU-Target: AMD A4-6400 APU
- Wohnort: Hamburg
@pluto
Für Synchronize solltest du dir eine Threadinterne Variable setzen, die den weiteren Ablauf bestimmt, z.B. SyncMode etwa so:
Dann kanst du in Execute den SyncMode setzen und Synchronized aufrufen. Je nach Zustand von SyncMode wird dann das entsprechende ausgeführt. Wenn der Thread während Synchronized keine neuen Daten produzieren darf, erreicht man das durch:
Für Synchronize solltest du dir eine Threadinterne Variable setzen, die den weiteren Ablauf bestimmt, z.B. SyncMode etwa so:
Code: Alles auswählen
type
TSyncModeSet = (sm_unknown, sm_itemsadd, sm_stoptimer,...);
TSyncMode = sm_unknown..sm_blabla;
TMyThread = class(TThread)
private
FSyncMode: TSyncMode;
Code: Alles auswählen
procedure TMyThread.Synchronized;
begin
case FSyncMode of
sm_itemsadd: begin
Suspended:= true;
// hier vielleicht einen Event aufrufen, der darf dann in TForm ausgeführt werden
Suspended:= false;
end;
end; // of case
end;
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.
(Ringelnatz)
(Ringelnatz)
-
- Lazarusforum e. V.
- Beiträge: 7192
- Registriert: So 19. Nov 2006, 12:06
- OS, Lazarus, FPC: Linux Mint 19.3
- CPU-Target: AMD
- Wohnort: Oldenburg(Oldenburg)
Natürlich ist für diese Aufgabe Thread Praktisch. Da ich noch andres sachen machen möchte. Wie oft den noch ?
z.b. möchte ich ein Archiv Öffnen und gleichzeitig Verzeichnisse Kopieren können.
Wie könnte man das ohne Thread denn Lösen ?
ich habe einen hinweis gefunden: auf http://www.delphipraxis.net/topic105368 ... ynchronize" onclick="window.open(this.href);return false;
wie ich das evlt. noch besser machen könnte.
Allerdings müsste ich dann ein Pointer mit Senden wegen TListItem.
Währe das Besser ? Sicherer ?
Also wie gesagt die Procedere Läuft und bis jetzt gab es noch keine Probleme.
Ich hoffe das bleibt auch so. Also auf Thread versiechten möchte ich nicht wie gesagt.
Aber ich bin für jeden Vorschlag dankbar, was ich anders machen könnten in der Thread Procedure.
Oder eine Altnative zu den Threads.
Mein Ziel ist es: ich möchte mehrer sachen gleichzeitig machen können.
Gut ich könnte Timer verwenden. Aber ich glaube das ist nicht so Praktisch.
edit:
@schnullerbacke
dein vorschlagt hat nur ein hacken: wie mache ich das mit Parameter ?
ich brauche welche.
Edit2:
ich glaube ich weiß wie du das meinst.
Die Parameter kann ich dann dem Ereignis übergeben, richtig ?
und das ist dann besser ?
was heißt Eigentlich: die VCL ist nicht Thread Sicher ?
Das habe ich jetzt einige male gelesen.
z.b. möchte ich ein Archiv Öffnen und gleichzeitig Verzeichnisse Kopieren können.
Wie könnte man das ohne Thread denn Lösen ?
ich habe einen hinweis gefunden: auf http://www.delphipraxis.net/topic105368 ... ynchronize" onclick="window.open(this.href);return false;
wie ich das evlt. noch besser machen könnte.
Allerdings müsste ich dann ein Pointer mit Senden wegen TListItem.
Währe das Besser ? Sicherer ?
Also wie gesagt die Procedere Läuft und bis jetzt gab es noch keine Probleme.
Ich hoffe das bleibt auch so. Also auf Thread versiechten möchte ich nicht wie gesagt.
Aber ich bin für jeden Vorschlag dankbar, was ich anders machen könnten in der Thread Procedure.
Oder eine Altnative zu den Threads.
Mein Ziel ist es: ich möchte mehrer sachen gleichzeitig machen können.
Gut ich könnte Timer verwenden. Aber ich glaube das ist nicht so Praktisch.
edit:
@schnullerbacke
dein vorschlagt hat nur ein hacken: wie mache ich das mit Parameter ?
ich brauche welche.
Edit2:
ich glaube ich weiß wie du das meinst.
Die Parameter kann ich dann dem Ereignis übergeben, richtig ?
und das ist dann besser ?
was heißt Eigentlich: die VCL ist nicht Thread Sicher ?
Das habe ich jetzt einige male gelesen.
Zuletzt geändert von pluto am Sa 28. Apr 2007, 16:43, insgesamt 1-mal geändert.
MFG
Michael Springwald
Michael Springwald