![]() |
Threads verwalten
Ich bin dabei ein Programm zu schreiben das verschiedene Dateien auf Änderungen überwacht. Jetzt will ich das aber in verschiedenen Threads machen. Meine Frage wie?
ein Thread soll haben: - 1 Komponente zur Überwachung (TfisFileNotification) - 1 Komponente zur Speicherung (Versionierung) der Änderung (TJvZlibMultiple) - dirverse einfache Variablen wie:
Delphi-Quellcode:
Nun weiß ich aber im Vorfeld nicht wieviele Threads ich brauche. Ich dachte da an eine TObjectList am besten eine typisierte (Name, WatchFolder, BackupFolder : string; IncludeFiles, ExcludeFiles, ExcludeFolder : string; minSize, maxSize : integer; ![]() Da ich aber noch nicht so tief in die Materie eingestiegen bin wollte ich wissen wie ich Threads in eine Liste verwalten kann. Die Threads sind von Natur aus (vielleicht bis auf die, von mir gewünschten, Meldungen fürs Log) unabhänig. Da habe ich schon was gefunden mit
Delphi-Quellcode:
kann ich aus den einzelnen Threads die Log füllen.
PostMessage(MainForm.Handle, MY_WM_USER, SUB_MESSAGE_X, Integer(InfoRecord));
Was ich jetzt noch wissen muß wie muß die Threadklasse aussehen, wie kann ich die zur Laufzeit erzeugen und wie verwalte ich die in der Liste? Ich hoffe ich habe mich verständlich ausgedrückt und falls das alles Quatsch ist, was ich geschrieben habe dann entschuldige ich mich schonmal. Danke David |
Re: Threads verwalten
Hmm, ist ja eine sehr allgemeine Frage.
Also, ja Du kannst viele Threads erzeugen und ale einer Objectliste hinzufügen. Ob du die Liste typisieren musst, liegt an dir und der Aufgabe selbst. Die Übergabe des Ergebnisses würde per Postmessage gehen, aber dazu muss InfoRecord extern auf dem Heap liegen, oder du verwnedest sendmessage. |
Re: Threads verwalten
PostMessage und SendMessage verwende ich auch sehr oft, darf ich da mal eine Zwischenfrage stellen:
Wie erreiche ich, dass InfoRecord auf dem Heap eingerichtet wird und damit PostMessage verwendet werden kann? Wird eine Unit-lokale Variable im Heap angelegt? |
Re: Threads verwalten
Nein, eine Unit-lokale Variable ist ja auch global. Das Problem daran ist, dass es die Variable nur einmal gibt - du musst also sicherstellen, dass du nicht die Daten überschreibst, bevor der Hauptthread sie abgeholt hat. Für den Heap brauchst du New und Dispose bzw. GetMem und FreeMem.
|
Re: Threads verwalten
unitlokal/global = heap
prozedurlokal = stack du mußt aber aufpassen, daß der Speicher nicht wieder überschrieben wird. z.B. mehrmals PostMessage mit diesem Speicher, aber das "Ziel" hat die gesendeten Nachrichten noch garnicht verarbeitet und somit würde der Speicher zurüh überschrieben. Du kannst aber z.B. mit GetMem Speicher reservieren, mit PostMessage versenden und am "Ziel" diesen Speicher dann wieder freigeben. (aber Achtung: einige Speichermanager muß man erst in einen Threadsicheren Modus versetzen, aber ich hoffe mal, daß dieses bei dir schon der Fall ist) |
Re: Threads verwalten
Hm? "Heap" ist doch normalerweise nur der Bereich, der vom Speichermanager verwaltet wird, und das ist bei globalen Variablen nicht der Fall. Kann aber sein, dass ich mich hier in der Terminologie irre.
|
Re: Threads verwalten
Danke, bisher funktioniert das alles recht gut!
Meine Anwendungsfälle sind allerdings nicht thread-bezogen, ich verwende das Verfahren um Nachrichten zwischen Units auszutauschen, die sich nicht kennen. So versendet z.B. die Konfiguration eine neu gesetzte Farbe und alle Units, die sich berufen fühlen, aktualisieren dann ausgewählte Controls. Äh, ja, ein Widerspruch ist da. Würde aber aufgrund fehlender Fehler (hihi) zu himitsu's Erklärung tendieren |
Re: Threads verwalten
Um auf die ursprüngliche Frage zurückzukommen, ja die Frage ist sehr allgemein.
So weit ich jetzt verstanden habe kann ich also eine Klasse wie die erstellen:
Delphi-Quellcode:
Und dann kann ich die TWatchThread Objekte einfach in eine TObjectList speichern?
TWatchThread = class(TThread)
private FileNotify : TfisFileNotification; FileZip : TJvZlibMultiple; Name, WatchFolder, BackupFolder : string; IncludeFiles, ExcludeFiles, ExcludeFolder : string; minSize, maxSize : integer; procedure OnNotifyChanged(Sender: TObject); public constructor Create(AOwner : TComponent); procedure Execute; override; end; procedure TWatchThread.Execute; begin FileNotify.Start; ... FlieNotify.OnChanged := OnNotifyChanged; end; procedure TWatchThread.OnNotifyChanged(Sender: TObject); begin // auf den Event reagieren // Liste der Dateien durchgehen, Änderungen mit FileZip speichern // So hier die Meldung für das Log ??? PostMessage(MainForm.Handle, MY_WM_USER, SUB_MESSAGE_NEW_SAVE, Integer(InfoRecord)); end;
Delphi-Quellcode:
Ich muß natürlich noch auf die Messages reagieren, aber hab ich das so richtig gemacht?
// Threads erstellen
begin ObjectList := TObjectList.Create; ObjectList.OwnsObjects := true; // für alle zu überwachende Verzeichnisse ObjectList.Add(TWatchThread.Create(Self)); end; // Threads starten begin aWatchThread := TWatchThread(ObjectList.Items[index]); aWatchThread.Execute; end; Danke David |
Re: Threads verwalten
Man ruft .Execute nicht direkt auf!
Und wo wie/wo ist InfoRecord definiert? |
Re: Threads verwalten
Delphi-Quellcode:
Sohier dachte ich.PInfoRecord = ^TInfoRecord ; TInfoRecord = record WatchThreadID : Cardinal; Meldung : string; end; procedure TWatchThread.OnNotifyChanged(Sender: TObject); var InfoRecord : PInfoRecord; begin // auf den Event reagieren // Liste der Dateien durchgehen, Änderungen mit FileZip speichern // Also so ??? New(FoundRecord); InfoRecord^.WatchThreadID := GUID; InfoRecord^.Meldung := 'Hier kommt der Text für die Meldung rein'; PostMessage(MainForm.Handle, MY_WM_USER, SUB_MESSAGE_NEW_SAVE, Integer(InfoRecord)); end; procedure TMainForm.ThreadMessage( var Message : TMessage ); var InfoRecord : PInfoRecord; ID : Cardinal; begin case Message.WParam of MY_WM_USER : begin InfoRecord := PInfoRecord(Message.LParam); ID := ThreadIDToIndex( InfoRecord^.WatchThreadID ); Memo.Lines.Add(InfoRecord^.Meldung); Dispose(InfoRecord); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz