In einem Trehad ein Dialog auf rufen und wieder schließen ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Christian
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:

Beitrag von Christian »

Das kannst du auch ohne Threads. Setz dich einfach mit dem was du machen willst mal auseinander, ansonsten brauchst du net Programmieren.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

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.
Ach Pluto. Vergiss einfach mal die extra Threads. Erstens kapierst du's scheint's nicht und zweitens brauchst du das nicht.
Extra Threads sollte man meiner Meinung nach nur dann verwenden, wenn man GENAU weiss wozu. In deinem Falle sind sie nicht nötig.

schnullerbacke
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

Beitrag von schnullerbacke »

@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.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

pluto
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)

Beitrag von pluto »

@schnullerbacke
Danke ! Der erste Praktische hinweis.
@Christian ich finde deine Beiträge etwas arrogant. nur weil du der Beste bist heißt das nicht das wir gleich mit dem was wir vorhaben aufgeben sollten.

im Gegenteil.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

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.

Christian
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:

Beitrag von Christian »

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/

pluto
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)

Beitrag von pluto »

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.
MFG
Michael Springwald

pluto
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)

Beitrag von pluto »

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;
So dieser Code scheint zu Funktionen. die Änderungen waren nur minimal. Aber es geht jetzt *Freu*
@Schnullerbacke
ich kann mit Synchronize leider keine Variablen Synchronizen genauso wenig einfache unit Prozeduren.
MFG
Michael Springwald

Christian
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:

Beitrag von Christian »

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/

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

pluto hat geschrieben: Aber es geht jetzt *Freu*
Nix 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!!!!!!!!!!!!!!

pluto
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)

Beitrag von pluto »

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.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

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.
Vor allem kannst du sie vergessen, weil du sie für diese Aufgabe nicht benötigst.
Aber das kann ich wohl noch hundert mal sagen. Es interessiert dich ja eh nicht.

schnullerbacke
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

Beitrag von schnullerbacke »

@pluto

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;
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:

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)

pluto
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)

Beitrag von pluto »

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.
Zuletzt geändert von pluto am Sa 28. Apr 2007, 16:43, insgesamt 1-mal geändert.
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

@Schnuller: Das kann man so machen. Den Thread anzuhalten ist aber nicht nötig.

Synchronize(@Synchronized) würde hier reichen.

Aber wozu das Ganze? Ich würde das wahrscheinlich ohne Thread machen.

Antworten