Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Nur ausführen, wenn es dadurch keine behinderung gibt


IhopeonlyReader - Di 19.03.13 11:57
Titel: Nur ausführen, wenn es dadurch keine behinderung gibt
Guten Tag,
ich habe mal eine Frage :D (mal wieder^^)
ich würde gerne eine Art Schleife programmieren, die allerdings nur dann durchläuft, wenn dadurch nichts anderes "behindert" wird..
Also wenn ich also eine For to schleife mache (von 1 bis 1 mio zB.) dann würde sich das prog, ja normalerweise aufhängen... also habe ich mir gedacht ich setze ein delay(1) dazwischen... das funktioniert auch, allerdings wenn ich jetz auf einen Button drücke, so ist diese prozedure erheblich verlangsamt...

ist es also möglich eine Schleife (z.B. auch nicht-endene schleifen zB while x=x do...) nur dann durchlaufen zu lassen, dass das Programm
- immer reagiert (nicht abstürzt)
- keine unnötige Verlangsamung da ist (von anderen Prozeduren etc)
- trotzdem schnell.. (bzw. die schleife schnell durchläuft, also keine unnötige Wartezeit wie delay(1))

Möglichkeiten: -timer (bin ich aber gegen, da es dadruch zu lange dauert...)
- jede prozedure so aufbauen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure blabla(Parameter: typ);
begin
eineProzlaeuft := true;
// eigentlicher procedure quelltext
eineProzlaeuft := false;
end;

//in der schleife dann
for C:=1 to 1000000 do if not eineProzlaeuft then 
begin
//durchlaufen
end;



Es geht um folgendes:
es sollen im Hintergrund records eingeladen werden, jedoch können das ziemlich viele sein, und dieser werden erst später benutzt...
wenn man nun auf "laden" geht, dann hängt sich das Programm für ein paar Minuten auf, ist dann aber fertig.. wenn man lange das Programm offen hat, sollen die records schon eingeladen sein, so dass man auf laden geht und man dann gar nichts mehr einladen brauch...

wie man das immer Hintergrund ausführt etc. ist ja alles kein Problem, aber so ausführen dass das Programm sich
- nicht aufhängt
und trotzdem eingeladen wird habe ich noch nicht vernünftig hintegkriegt


Nersgatt - Di 19.03.13 12:00

Du musst Dich in das Konzept der Threadprogrammierung einarbeiten. Das ist genau das, was Du suchst. Das Thema ist nicht ganz ohne, es lohnt sich aber.
Ich empfehle Dir diese Seite als Einstieg: http://www.delphi-treff.de/tutorials/objectpascal/threads/einleitung/


jfheins - Di 19.03.13 12:00

Lösung: Threads.

Wobei selbst das laden von 1 Mio records nicht besonders lange dauern dürfte... Hast du da ml Code wie du das aktuell machst?


IhopeonlyReader - Di 19.03.13 12:25

Threads also :) danke
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
... Hast du da ml Code wie du das aktuell machst?



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
var   Dateiname, ZeilenInhalt: String;
         TF: TextFile;
         C, ADDp: Integer;
         SR: TSearchRec;
begin
//Pfad wird als Parameter übergeben
//herausfinden von Dateiname 
ADDp := 0;
  if FindFirst(Pfad + '*.txt', faAnyFile, SR) = 0 then
   begin
     repeat
     if (SR.Attr <> faDirectory) then
       begin
       Dateiname := '\'+SR.Name
       try
       AssignFile(TF, Pfad+ Dateiname);
       Reset(TF);
       ReadLn(TF,Zeileninhalt);
       For C := 1 to 4 do
         begin
         ReadLn(TF, ZeilenInhalt); 
         // Zeileninhalt behandeln 
         //ZB. Recordname[ADDP].Erste[C] benötige variable... 
         end
       ReadLn(TF, ZeilenInhalt); 
       // Zeileninhalt behandeln
       //ZB. Recordname[ADDP].Zweite benötige variable... 
//alle weiteren zeilen auslesen...
         finally
         CloseFile(TF);
         end
       inc(ADDp);
       end;
     until FindNext(SR) <> 0;
     FindClose(SR);
   end;


WasWeißDennIch - Di 19.03.13 12:33

Für das Suchen der Dateien kenne ich eine Komponente, die das bereits in einem Thread erledigt. Vielleicht ist sie ja etwas für Dich: TFileSearcher [http://www.torry.net/quicksearchd.php?String=tfilesearcher&Title=Yes]


IhopeonlyReader - Di 19.03.13 12:51

So wie ich das verstanden habe, sucht TFilesearch nur nach einer bestimmten Datei in einem Ordner... aber ich gehe ja alle Dateien in dem ordner durch und aus jeder Datei hole ich mir meine daten


WasWeißDennIch - Di 19.03.13 12:54

Das hast Du falsch verstanden. Du gibst ein Verzeichnis und eine Suchmaske an, rufst Execute auf, und bei jedem Fund wird das OnMatchFound-Ereignis abgearbeitet.


IhopeonlyReader - Di 19.03.13 12:58

ja :D also wenn ich z.B. nach Pfad := 'Test.txt' suche, gibt er mir alle Test.txt s aus und führt die proz aus... aber
1. die unterordner sollen nicht mit durchsucht weden,
2. Pfad '*.txt' liefert wahrscheinlich sehr viel !, daher finde ich findfirst besser


WasWeißDennIch - Di 19.03.13 13:03

Ohne Unterordner: Recursive auf false stellen (Standard). Und intern arbeitet das Ding ja auch mit FindFirst, da ist doch keine Hexerei dahinter. Daraus folgt, dass Du wie sonst auch entsprechende Wildcards als Suchmaske angeben kannst, bei Bedarf sogar mehrere davon.


IhopeonlyReader - Di 19.03.13 13:24

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Und intern arbeitet das Ding ja auch mit FindFirst.


warum soll ich dann nicht selber findfirst nutzen? ich denke das ist schneller^^
und auch nicht gerade schwer zu programmieren also insofern :D.. da es jetz schon programmiert ist, sehe ich eh nur Vorteile in meiner weise


WasWeißDennIch - Di 19.03.13 14:07

Und was ist mit Deinem Thread? Den musst Du ja auch erst einmal programmieren. Aber ich will Dir ja nichts aufschwatzen, es war nur ein gut gemeinter Vorschlag.


IhopeonlyReader - Do 25.04.13 19:21

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Du musst Dich in das Konzept der Threadprogrammierung einarbeiten.

Habe ich jetzt.. hat zwar gedauert bis ich dazu gekommen bin, aber lohnt sich wirklich :)

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Das Thema ist nicht ganz ohne, es lohnt sich aber.

naja in Delphi gibt es die "vordefinierte" klasse TThread, hierdurch ist das ganze SEHR einfach. man muss halt nur auf Deadlocks aufpassen^^


user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Ich empfehle Dir diese Seite als Einstieg: http://www.delphi-treff.de/tutorials/objectpascal/threads/einleitung/


mhh... ich finde http://wiki.delphigl.com/index.php/Tutorial_Multithreading ist SEHR viel einfacher gestaltet.. aber jede seine Meinung

DANKE nochmal ;)


GuaAck - Do 25.04.13 20:29

Zwar schon beantwortet, trotzdem:

Ich vermisse Verweise auf die Priority. In der Windows SDK gibt es den Befehl "SetPriorityClass". Wenn man die Priority auf "IDLE_PRIORITY_CLASS" setzt, dann wird nichts anderes behindert, der Prozess läuft nur, wenn der Rechner sonst nichts zu tun hätte. Auch "TThread.Priority" kann in diesem Zusammenhang hilfreich sein.

Gruß
GuaAck