Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Result als mehrdimensoiertes array im Thread (https://www.delphipraxis.net/191332-result-als-mehrdimensoiertes-array-im-thread.html)

alfold 4. Jan 2017 10:50

AW: Result als mehrdimensoiertes array im Thread
 
Mh, Result muss ja irgendwann mal die Größe bekommen!
also muss ich im getter Result bei der Abfrage vom Meinthread setzen.
Oder ich könnte Result vorher abfragen ob es schon gesetzt ist. Ob das geht, hab ich noch nicht getestet?

Ursache ist aber EXECUTE dort sind die daten nicht fix. Demzufolge auch nicht im Getter. Wie sich herraustellte. Warum keine Ahnung!
Bin noch am suchen:gruebel:

Den getter hab ich jetz erstmal ganz entfernt!
Gruß

Mavarik 4. Jan 2017 11:26

AW: Result als mehrdimensoiertes array im Thread
 
Dein Getter der die Werte abfragt kümmert sich nicht darum ob der Thread noch läuft...

Vielleicht leitest Du mal Deine Klasse von meinem mini-Threadhelper ab...

Mavarik...

stahli 4. Jan 2017 11:27

AW: Result als mehrdimensoiertes array im Thread
 
Übersichtlicher wäre es sicher, das Array im Mainthread zu erstellen und dem nebenläufigen Thread zu übergeben (
Delphi-Quellcode:
MyThread := TMyThread.Create(MyArray)
)

Den Zugriff musst Du aber auf jeden Fall absichern bzw. synchronisieren.

alfold 4. Jan 2017 11:37

AW: Result als mehrdimensoiertes array im Thread
 
Danke für alles!
Fehler gefunden. Ich hab im Mainthread ausversehen den Thread 2x erstellt. Deswegen auch immer execute der Fehler daten da/nicht da.:oops:

Das Absichern kommt jetzt!
Synchronisieren mit den Mainthread? Nö
Hat seine Grund.

THX für Eure Bemühngen

Gruß Alfold
und damit keine offene Frage mehr.

Fritzew 4. Jan 2017 12:16

AW: Result als mehrdimensoiertes array im Thread
 
Also ich würde das in etwa so umsetzen:

Delphi-Quellcode:
unit newLwThread;

interface

uses
   Windows,
   Classes,
   SysUtils,
   Syncobjs;

type

   tarray = array [1 .. 4] of array of Boolean;

   TnewLwThread = class(TThread)
   private
      FEvent: TEvent;
      fFileList: array [1 .. 4] of TStringList;
      fisfilea: tarray; // array[1..4] of array of Boolean;
      fIsFileIndex: Integer;
      fIsListIndex: Integer;

      fLock: array [1 .. 4] of Tcriticalsection;

      procedure setFileList(index: Integer; const Value: TStringList);
      function Getfile: tarray;

   protected
      procedure Execute; override;

   public
      constructor Create;
      destructor Destroy; override;
      procedure ContinueWork;
      procedure Terminate;

      property Titel[index: Integer]: TStringList write setFileList;
      property isfile: tarray read Getfile;
   end;

implementation

{ TnewLwThread }

constructor TnewLwThread.Create;
var
   i: Integer;
begin
   inherited Create(true);
   FEvent := TEvent.Create(nil, false, false, '');
   for i := 1 to 4 do
      begin
         fFileList[i] := TStringList.Create;
         fLock[i] := Tcriticalsection.Create;
      end;
   FreeonTerminate := false;

end;

destructor TnewLwThread.Destroy;
var
   i: Integer;
begin
   ContinueWork;
   if not Terminated then
      begin
         Terminate;
         ContinueWork;
         WaitFor;
      end;
   for i := 1 to 4 do
      begin
         fFileList[i].Free;
         fLock[i].Free;
         SetLength(fisfilea[i], 0);
      end;
   FEvent.Free;
   inherited;
end;

procedure TnewLwThread.ContinueWork;
begin
   (* Event auf Signaled setzen *)
   FEvent.SetEvent;
end;

procedure TnewLwThread.setFileList(index: Integer; const Value: TStringList);
begin
   if index in [1 .. 4] then
      begin
         fLock[index].Enter;
         fFileList[index].Clear;
         fFileList[index].Assign(Value);
         SetLength(fisfilea[index], fFileList[index].Count);
         fLock[index].Leave;
      end;
end;

procedure TnewLwThread.Execute;
var
   i, x: Integer;
begin
   while not Terminated do
      begin
         if (FEvent.WaitFor(INFINITE) = wrSignaled) and not Terminated then
            begin
               // checkfile;
               for i := 1 to 4 do
                  begin
                     fLock[i].Enter;
                     try
                        if fFileList[i].Count > 0 then
                           begin
                              for x := 0 to fFileList[i].Count - 1 do
                                 begin
                                    if FileExists(fFileList[i].Strings[x]) then
                                       if not fisfilea[i][x] then
                                          fisfilea[i][x] := true
                                       else if fisfilea[i][x] then
                                          fisfilea[i][x] := false;

                                 end;
                           end;
                        // getfile;
                     finally
                        fLock[i].Leave;
                     end;
                  end;

            end;
      end;
end;

procedure TnewLwThread.Terminate;
begin
   inherited Terminate;
   FEvent.SetEvent;
end;

function TnewLwThread.Getfile: tarray;
var
   i, j: Integer;
begin
   for i := 1 to 4 do
      begin
         fLock[i].Enter;
         try
            SetLength(result[i], length(fisfilea[i]));
            for j := 0 to length(fisfilea[i]) - 1 do
               result[i, j] := fisfilea[i, j];
         finally
            fLock[i].Leave;
         end;
      end;
end;

end.

p80286 4. Jan 2017 12:33

AW: Result als mehrdimensoiertes array im Thread
 
Zitat:

Zitat von alfold (Beitrag 1358034)
Synchronisieren mit den Mainthread? Nö
Hat seine Grund.

Synchronisieren bedeutet nicht irgendeine Funktion aufzurufen, sondern sicher zu stellen, daß nicht zwei Threads gleichzeitig auf ein und den selben Speicherbereich zugreifen.

sollte sich das "nö" hierauf beziehen solltest Du u.U. dein Hobby wechseln.

Gruß
K-H

himitsu 4. Jan 2017 13:17

AW: Result als mehrdimensoiertes array im Thread
 
Zitat:

Zitat von stahli (Beitrag 1358024)
PS: Reserviert SetLength evtl. sogar neuen Speicher, wenn sich die bisherige Größe dadurch gar nicht ändert? Bin hier unsicher.

SetLenght sorgt für ein UniqueArray. Wenn also aktuell mehrere Variablen auf dieses Array zeigen, dann legt SetLength eine neue Kopie an.

alfold 4. Jan 2017 17:38

AW: Result als mehrdimensoiertes array im Thread
 
Zitat:

Zitat von p80286 (Beitrag 1358042)
Zitat:

Zitat von alfold (Beitrag 1358034)
Synchronisieren mit den Mainthread? Nö
Hat seine Grund.

Synchronisieren bedeutet nicht irgendeine Funktion aufzurufen .....
sollte sich das "nö" hierauf beziehen solltest Du u.U. dein Hobby wechseln.

Gruß
K-H

Sorry ich dachte an synchronize mit den Mainthread:?
alles andere kommt jetzt dazu!

der Getter sieht jetzt so aus
Delphi-Quellcode:
function TLwThread.Getfile: tarray;
var
  i: Integer;
begin
    LwCS.Enter;
    try
       for i:= 1 to 4 do
       begin
             Result[i]:= Copy(fisfilea[i]);
       end;
    finally
      LwCS.Leave;
   end;
end;
@Fritzew
Macht das sinn für jedes Array ein CriticalSection?
Es wird eh einmal gelesen oder geschrieben? Zwischen durch darf kein anderer ran.

Gruß alfold

Fritzew 4. Jan 2017 19:31

AW: Result als mehrdimensoiertes array im Thread
 
Zitat:

Macht das sinn für jedes Array ein CriticalSection?
Es wird eh einmal gelesen oder geschrieben? Zwischen durch darf kein anderer ran.
Wie stellst Du sicher das keiner ran will?
Das war einfach auf die Schnelle um das Prinzip darzustellen.

Sperren sollten immer so kurz wie möglich sein, das war mit den Stringlisten das kürzeste:-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:57 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz