Re: Liste Thread sicher abholen
Ich verstehe einfach nicht, wieso Du keine TThreadlist nimmst... (Ich verstehe auch nicht, wieso Du nicht einfach eine 'TCriticalSection' verwendest. Dafür hast Du doch Delphi, damit Du dich nicht/seltener mit der API rumschlagen musst)
So gehts im Prinzip:
Delphi-Quellcode:
Dein Thread erstellt also eine neue EnumWindowsList und schmeisst Die dann per o.g. Code in die ThreadListe. Wenn jemand von außen die Liste will, macht er das genauso:
Var
LocalList : TList; Begin LocalList := MyThreadList.LockList; Try // ... tuwat mit der LocalList Finally MyThreadList.Unlock; End End;
Delphi-Quellcode:
Fertig.
Procedure TMyThread.AssignToThreadList (aList : TList);
Var LocalList : TList; Begin LocalList := MyThreadList.LockList; Try LocalList.Assign (aList); Finally MyThreadList.Unlock; End End; Procedure TMyThread.GetFromThreadList (aList : TList); Var LocalList : TList; Begin LocalList := MyThreadList.LockList; Try LocalList.AssignTo (aList); Finally MyThreadList.Unlock; End End; Procedure TMyThread.Excute; Var MyList : TList; Begin While not Terminated Do Begin CreateWindowList (MyList); AssignToThreaDList (MyList); Sleep(SomeTime); // sonst geht doch die CPU auf 100% End Wenn Du eine CS willst, dann geht das damit (fast) genauso. Aber wieso das Rad neu entwickeln. Dazu gibt es schließlich die TThreadlist. |
Re: Liste Thread sicher abholen
ok, debuggen kann ich also noch. Folgende und eingentlich auch logische Situation.
aktiviere ich Lock im Execute, so geht der LockCounter auf 0 und OwnerThread ist mein Thread. Aktiviere ich Lock in der GetterMethode des Thread durch Auffruf derselben durch meine Application, so ist OwnerThread meine Exe. Damit scheint meine Theorie zu stimmen, dass ich mich selber (Thread) sperre wenn ich mit dem MainThread über die GetterMethode komme. Es entsteht wieder Wissen :drunken: in meinem Kopf. Nächster Schritt, wie mache ich jetzt die aktualisierung meiner Liste im Execute sicher? Es geht vorwärts. oki |
Re: Liste Thread sicher abholen
[war ja klar, roter Kasten]
Hi alzaimar. Du hast völlig recht! Zwei Gründe von meiner Seite. 1. Wollte ich das mit CriticalSection verstehen, was ich so langsam tue (auch wenn es der steinige Weg über ein erstmal falsches Vertehen ging). 2. In meinem Kopf ging irgent was verquerr, so das mir jetzt erst dämmert wie der richtige Weg ist. Da der Thread noch ne Menge mehr machen soll dachte ich, dass ich hier das Problem an einer Stelle zentral erschlagen könnte. Ich mach jetzt erst mal 'ne kurze Pause an der Stelle und verpass meinem Kopf ne mentale Reinigung um die verqueren Gedanken los zu werden. Danach bau ich alles mal sauber um und wenn das ordentlich aussieht, dann poste ich meinen Weg. Ich denk mal, das sollte auch für andere interessant sein. Großen Dank an Sirius und natürlich auch an alzaimar für die Hilfe. Ich lass den Thread noch so lange offen, bis ich das saubere Ergebnis habe. Gruß oki [Edit] Nachtrag: Tut mir leid, wenn ich etwas verbohrt bin, aber ich schau erst mal bei TCriticalSection nach. Das hab ich ganz übersehen, sieht aber irgentwie nach meiner Ideallösung aus. Ich mach mal ein paar Lernstunden. Ist immer gut (und ich dachte ich kenn mich halbwegs mit Threads aus. Totaler Blödsinn).[/Edit] |
Re: Liste Thread sicher abholen
Hauptsache, man lernt was. CS sind allgemeiner und damit löst man das 'Threadlisten-Problem' auch.
Wichtig!!!! CS sperren nur unterschiedliche Threads, jedoch nicht konkurrente Aufrufe aus ein und demselben Thread. Wenn Du das willst, dann benötigst Du die große Schwester, die Semaphore. |
Re: Liste Thread sicher abholen
Zitat:
Vom Prinzip her will ich folgendes. Aktualisiere ich meine Listen sollen die Threads von außen warten bis ich fertig bin. Ist das so, dürfen die ran. Dann muss ich im Thread sicher stellen, dass ich erst anfange erneut zu aktualisieren wenn die von außen fertig sind. Ob den zweiten Teil TCriticalSection liefert ist mir noch nicht klar, den ersten aber sicher. Die OH sagt dazu zumindestens: Zitat:
oki |
Re: Liste Thread sicher abholen
Doch doch, die CS ist dein Freund. Einfach blind alle Zugriffe auf dein schützenswertes Objekt kapseln und gut is.
|
Re: Liste Thread sicher abholen
Ok dann auch noch mal von mir konkret nachgehagt (deine Nettigkeit muß ich ausnutzen :stupid: ).
Mein zu schützendes Object ist meine Liste, TCriticalSection bringe ich in meinem Thread als Member unter und den Schutzmechanismus schalte ich immer ein, wenn auf die Liste zugegriffen wird. Also sowohl in den Getter- und Settermethoden des Threads für den Zugriff auf die Listen von außen wie auch in meinem Execute wenn ich die Listen im Thread aktualisiere. Schlicht immer. [Edit] Oder gehört die TCriticalSection in die Liste als Member? [/Edit] Mein Thread ist sozusagen das Portal nach außen für meine Listen, macht und tut mit den Listen rum und kümmert sich nebenbei um die sauberen Zugriffe von Außen auf die Listen (also threadsicher). So würde ich es populärwissenschaftlich ausdrücken. :lol: oki [Edit] Schnell noch einen Rechtschreibfehler nach Hause geholt. [/Edit] |
Re: Liste Thread sicher abholen
Genauso würde ich das machen. CS ist ein privates Feld des Threads und schützt die öffentlichen Eigenschaften des Threads, sodaß sich Thread und Verwender (ein anderer Thread) nicht auf die Füße treten.
Allerdings ist es etwas hübscher, wenn die Liste selbst dafür sorgt, das man gar nicht ungeschützt an sie rankommt (=TThreadlist). Du kannst spaßenshalber (wenn Du die CS gefressen hast) mal so eine threadsichere Stringliste bauen, die gibt es imho in der VCL nicht. Es ist zwar viel blöde Schreibarbeit (immer das Gleiche: CS.Enter try tu was finally CS.Leave) aber dann kannst Du das -rein schon wegen Pavlow- im Schlaf. :stupid: Ach, immer ausnutzen. Bin ja selbst Schuld, wenn ich hilfsbereit bin :zwinker: |
Re: Liste Thread sicher abholen
Ahhhmmm, so'n gepflegtes Mittagessen ist doch was wert.
Ich werd mal jetzt anfangen und den Code umsetzen. Das mit dem Tippen an der Tringliste [Edit] Ups, hatte doch was mit Unterwäsche zu tun und sollte StringList lauten :lol: [/Edit][Edit2]An der StringList tippen ist in diesem Kontext auch niedlich :lol: (ist mir grad so aufgefallen, Sorry)[/Edit2] seh ich nicht so kritisch. Da schreibt man sich dann mal eine neue Basisklasse TThreadStringList oder legt sich ein kleines Template an wenn man spezielle Klassen in Objects speichern will um sich das ständige Casten zu spaaren. Hab ich so auch mit einer ObjectList gemacht. Ist total easy. Gruß oki |
Re: Liste Thread sicher abholen
Menne, Erfolg auf der ganzen Linie :bounce2: !!!
Wenns denn auch wirklich sicher läuft? Aber das sollte es schon tun. Auf irgend was muss man sich halt auch einfach mal verlassen. Der Basiscode ist auch erschreckend simpel. So hatte ich mir das auch vorgestellt.
Delphi-Quellcode:
Ist eingendlich nicht viel für sooon langen Thread.
type
TShutDownThread = class(TThread) private FCS: TCriticalSection; // CriticalSection FShutDownList : TShutDownList; // Schließliste FWindowList : TWindowList; // Liste der aktiven Fenster FInterval : Integer; // Refreshzeit in ms protected procedure Execute; override; procedure UpdateWindowList; // Fensterliste aktualisieren public constructor Create(CreateSuspended: Boolean); reintroduce; virtual; Destructor Destroy; override; Procedure GetWindowList(const AList : TWindowList); // Fensterliste abholen property Interval : Integer read FInterval write FInterval; end; implementation { TTShutDownThread } constructor TShutDownThread.Create(CreateSuspended: Boolean); begin inherited; FCS := TCriticalSection.Create; FWindowList := TWindowList.Create; FShutDownList := TShutDownList.Create; FInterval := 200; end; destructor TShutDownThread.Destroy; begin FCS.Enter; try FreeAndNil(FWindowList); FreeAndNil(FShutDownList); inherited Destroy; finally FCS.Leave; try FreeAndNil(FCS); except end; end; end; procedure TShutDownThread.Execute; begin while not Terminated do begin FCS.Enter; try FWindowList.EnumTopLevelWindows; Sleep(Interval); finally FCS.Leave; end; end; end; procedure TShutDownThread.GetWindowList(const AList: TWindowList); var WinParamObj: TWinParamClass; begin if not Assigned(AList) then Exit; FCS.Enter; try AList.AssignList(FWindowList); finally FCS.Leave; end; end; procedure TShutDownThread.UpdateWindowList; begin FWindowList.EnumTopLevelWindows; // Alle Windows auflisten end; Ich hoffe jetzt kommt nicht einer um die Ecke und erklärt mir, dass das alles totaler Stuß ist was ich hier schreibe. Drücken wir mal die Daumen. Erläuterungen brauch jetzt wohl nicht mehr machen. Der Thread erzählt genug. Herzlichen Dank an alle. Das sauber zu lösen war mir wichtig. Gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:02 Uhr. |
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