![]() |
Re: CPU Auslastung für ein Programm begrenzen
Hast du dir die Beiträge von Klaus und Domink mal durchgelesen? Das sind zwei Lösungsvorschläge, wobei der mit den Threads wohl vorzuziehen wäre.
|
Re: CPU Auslastung für ein Programm begrenzen
Bei exakt diesem Code kann ich nicht verstehen, warum er 5-10 Minuten arbeitet. Und man kann am Code noch einiges vereinfachen/verschönern. Zum Beispiel die 2 aufeinanderfolgenen for-Schleifen zu einer zusammenzufassen, iCell brauchst du auch nicht, oder du lässt i weg.
Threads kann ich hier auch vorschlagen und vielleicht solltest du den Code nochmal überarbeiten. Flare |
Re: CPU Auslastung für ein Programm begrenzen
Hallo,
ich habe mir mal erlaubt, den Code etwas zu überarbeiten. Es gibt zwar sicher noch mehr zu optimieren, aber ich habe mich auf das Nötigste beschränkt. Erstens sind jetzt ein paar Ressourcen-Schutzblöcke mit 'drin, und zweitens hab ich von Textfile aud TStringlist umgestellt. Schau' mal, ob das so schneller läuft.
Delphi-Quellcode:
Übrigens: Es sieht so aus, als würde diese Funktion mehrfach aufgerufen. Wenn ja, wie oft bzw. wie sieht der aufrufende Code aus?
procedure TMain_Form.prCreateXls(iAnzRec : Integer);
var bl : Boolean; oleExcelApp, oleExcelSheets, oleExcelWorkb : OleVariant; i, j, iCount, iRow : Integer; sDate, sFile, sPath, sRow, sXlsFile : String; wRC : Word; SL: TStringList; begin //Paths sDate := FormatDateTime('yyyymmdd', Date); sFile := 'U:\Programmierung\LOG\Router_Tab\Excel\ROUTES_TAB_' + sDate; sPath := '..\Output\ROUTES_Convert_' + sDate + '.txt'; //Create .xls / Set Column Format / Create Header try oleExcelApp := CreateOleObject('Excel.Application'); oleExcelWorkb := oleExcelApp.Workbooks.Add; oleExcelSheets := oleExcelworkb.WorkSheets.Add; oleExcelSheets.Name := 'Router Tab vom ' + sDate; iRow := 1; For i := 1 To 7 Do Begin oleExcelSheets.Columns[i].NumberFormat := '@'; oleExcelSheets.Cells[iRow, i].Font.FontStyle := 'Bold'; case i of 1: oleExcelSheets.Cells[iRow, i].Value := 'Land'; 2: oleExcelSheets.Cells[iRow, i].Value := 'PLZ Von'; 3: oleExcelSheets.Cells[iRow, i].Value := 'PLZ Bis'; 4: oleExcelSheets.Cells[iRow, i].Value := 'O - Sort'; 5: oleExcelSheets.Cells[iRow, i].Value := 'D - Depot'; 6: oleExcelSheets.Cells[iRow, i].Value := 'D - Sort'; 7: oleExcelSheets.Cells[iRow, i].Value := 'Barcode ID'; end; End; iCount := 100; //Assign .txt File for Input SL := TStringList.Create; try try SL.LoadFromFile(sPath); iRow := 2; for j := 0 to SL.Count - 1 do begin For i := 1 To 7 Do Begin sRow := SL[j]; case i of 1: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 1, 2); 2: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 3, 9); 3: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 12, 9); 4: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 21, 4); 5: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 25, 4); 6: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 29, 4); 7: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 33, 3); end; End; Inc(iRow); //Set Progress in Progress Bar If iRow = iCount Then Begin ProgBar2.Position := Round((100 * iRow) / iAnzRec); iCount := iCount + 100; End; end; except ShowMessage('Error opening file!'); end; finally SL.Free; end; //Examine whether File is present bl := FileExists(sFile + '.xls'); If bl = True Then Begin wRC := MessageDlg('File is allready present!' +#13+ 'Clear File?', mtInformation, mbYesNo, 0); If wRC = mrYes Then Begin bl := DeleteFile(sFile + '.xls'); If bl = False Then Begin ShowMessage('Error with File Clear!'); End; End Else Begin ShowMessage('File would be Overwritten!'); End; End; //Save as .xls File sXlsFile := ChangeFileExt(sFile, '.xls'); Try oleExcelWorkb.Close(true, sXlsFile, false); Except ShowMessage('Save To File Error'); End; //Excel freigeben finally oleExcelSheets := Unassigned; oleExcelWorkb := Unassigned; oleExcelApp.Quit; oleExcelApp := Unassigned; end; ProgBar2.Position := 0; lbl_sts_xls.Caption := 'Export to Excel. OK'; lbl_sts_xls.Font.Size := 8; lbl_sts_xls.Font.Color := clGreen; Main_Form.Refresh; bitbtn_exit.Enabled := True; end; Gruß xaromz |
Re: CPU Auslastung für ein Programm begrenzen
Delphi-Quellcode:
Hallo Andreas,//Assign .txt File for Input {$I-} AssignFile(txtFile, sPath); Reset(txtFile); {$I+} if IOResult = 0 then begin iCount := 100; iRow := 2; While Not EOF(txtFile) Do Begin Application.ProcessMessages; Readln(txtFile, sRow); //Add sRow to Excel Cells For i := 1 To 7 Do Begin case i of 1: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 1, 2); 2: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 3, 9); 3: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 12, 9); 4: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 21, 4); 5: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 25, 4); 6: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 29, 4); 7: oleExcelSheets.Cells[iRow, i].Value := Copy(sRow, 33, 3); end; End; iRow := iRow + 1; //Set Progress in Progress Bar If iRow = iCount Then Begin ProgBar2.Position := Round((100 * iRow) / iAnzRec); iCount := iCount + 100; End; End; end; CloseFile(txtFile); wenn Du schon mit {$I-} und {$I+} arbeitest solltest Du auch IOResult in irgendeiner Art und Weise abfragen. Ansonsten finde ich die Version mit dem Zeileweisen einlesen im Hinblick auf den Speicherverbrauch schonender als die Version von xaromz. Grüße Klaus |
Re: CPU Auslastung für ein Programm begrenzen
Zitat:
ich habe deshalb nach weiteren lösungen gefragt weil ich mir unsicher war, ob der vorschlag von klaus01 das gewünschte ergebniss bringt (da ich noch nicht so bewandert bin in der delphi programmierung, und da jemand anders die antwort in frage gestellt hat) und weil von thread programmierung keine ahnung hab und mir im moment die zeit dazu fehlt für das aktuelle projekt das auszuprobieren... ich benutze dieses forum hier nicht dafür das mir einer die lösung auf dem silbernen tablett serviert, ich benutze dieses forum dafür in bestehenden artikeln nach lösungen zu suchen und wenn ich nichts passendes finde einen neuen beitrag zu eröffnen um mein problem euch hier zu schildern in der hoffnung hinweise zu bekommen die auf die lösung meines problems hindeuten!!! soviel dazu von meiner seite... @flare warum kannst du nicht verstehen das er hierfür so lange braucht??? ok, ich weiß nicht was die normale verarbeitungs zeit für sowas ist, aber in anbetracht des datenvolumens, find ich das "aktzeptabel" ok, am code kann ich noch einiges verschönern, er sieht teilweise deshalb so komisch aus, weil ich hierfür die informationen hab zusammen suchen müssen, und ich endlich froh war das es läuft ;) @xaromz danke für deine mühe... ich werd den source code von dir bei gelegenheit mal in mein programm einbauen und testen... der aufrufende code ist ganz einfach ^^ die procedure wird über einen button auf der form aufgerufen :mgreen: die procedure läuft also so oft der anwender denn button betätigt... im normal fall nur einmal ;) |
Re: CPU Auslastung für ein Programm begrenzen
Zitat:
|
Re: CPU Auslastung für ein Programm begrenzen
Zitat:
naja... imho haben wir etwas aneinander vorbeigeredet ;) |
Re: CPU Auslastung für ein Programm begrenzen
Hallo Andreas,
Application.ProcessMessages ist dann sinnvoll wenn ein Programm lange Schleifen abzuarbeiten hat. Es ermöglicht es dem Programm Messages die für das Programm bestimmt sind abzuarbeiten. Das Programm erscheint dann nicht so, als ob es eingefroren wäre. Dein Programm würde dann auf minimize oder maximize oder auch auf andere Ereignisse reagieren. Sorry, hatte das zu meinem ersten Beitrag hinzugefügt. Grüße Klaus |
Re: CPU Auslastung für ein Programm begrenzen
ah ok gut danke für denn tipp klaus01
^^ jetzt weiß ich auch warum ich teilweise probleme mit meiner form hatte wenn ich mit anderen applikationen nebenher weitergearbeitet habe... |
Re: CPU Auslastung für ein Programm begrenzen
Hi,
@Andidreas Sorry aber als etwas Aussenstehender finde ich deine Kritik, dass du doch nach weiteren Lösungen fragen kannst etwas nun ja. Natürlich kannst du immer nach weiteren Lösungen fragen, bis dir eine gefällt aber ich denke dass wäre doch irgendwie etwas ignorant. Ich denke das was Luckie sagte war nicht böse gemeint (hast du hoffentlich auch nicht so aufgefasst), aber letztlich sagt er ja nur, dass du da zwei Möglichkeiten hast. Das du noch nicht mit Threads gearbeitet hast ist ja ok, aber du sagst nirgends, warum das jetzt ein Problem ist. Ich meine du wirst wahrscheinlich mit mehr Techniken nicht gearbeitet haben als umgekehrt, geht doch den meisten so. Aber wenn du eine Technik nicht kennst, dann such doch einfach ein wenig was dazu, zu Threads z.B. in der DP ;-) Ich meine das nicht böse, ich persönlich fand nur deine Reaktion etwas weit hergeholt. Was Threads angeht, so ist es recht einfach mit ihnen zu arbeiten. Das gilt überhaupt nicht pauschal, aber für dein Problem. Die Grundlagen liegen allerdings auch hier im Beitrag von xaromz, der sagte ja schon, dass Windows deine Rechenzeit verwaltet. Kein Prozess weiß, wieviel CPU Zeit es bekommt (es denkt immer es hätte 100% CPU Zeit, 100% vom Speicher und sei das Einzigste Programm auf der Welt). Für Threads gilt eigentlich das Selbe (beides ist stark vereinfacht). Jedenfalls schaltet Windows ganz ganz schnell zwischen einzelnen Programmen und Threads hin und her. Ein Programm hat dann immer für eine gewisse Zeit (die das Programm nicht kennt) die CPU und den Speicher. Läuft die Zeit ab, speichert Windows den Zustand und kopiert den zurück, bevor das Programm das nächste mal dran ist. Hier hast du dann jetzt die Möglichen Probleme beim Threading, laufen zwei Threads parallel, so weißt du nicht wo sich welcher Thread wann befindet. Greifen beide auf ihren Speicher zu, ist das kein Problem. Teilen sie sich aber irgendeinen Bereich, so kann es hier zu Konflikten kommen. Ein Beispiel wäre eine Bank. Sagen wir du hast einen Thread, der etwas abbucht und einen der etwas gutschreibt. Sagen wir noch auf deinem Konto sind gerade 1000 Euro. Der eine Thread möchte 500 Euro gutschreiben, der andere möchte 1000 abbuchen. Die einzelnen Schritte sehen ungefähr so aus:
Beim Threading laufen beide Prozesse gleichzeitig. Es kann nach jedem der drei Schritte zur Ausführung des jeweils anderen Thread kommen. Ein Problem wäre, wenn sich beide gleichzeitig den alten Kontostand holen (1000 Euro), dann beide den Betrag gutschreiben/abziehen und nun kommt es drauf an, wer zuerst speichert. Wird erst der abgezogene Betrag gespeichert, wäre der letzte Stand der gespeichert wird 1500 Euro (+), gut für dich schlecht für deine Bank. Andersrum würde es aber zu 0 Euro führen (schlecht für dich! und die Bank hätte Geld verloren, auch nicht gut). Solange du aber einen Thread die eigentliche Arbeit sequentiell machen lässt (er also als einziger auf seinen Daten arbeitet), kann dir das alles egal sein. Da wird der Thread halt als neuer Prozess nebenbei gestartet (und es kommt nie zu einem Konflikt). Wie man das genau macht, entnimmst du am besten einem Tutorial zum Thema Threads oder schaust in die OH. TThread heißt hier das Schlüsselwort. Was die Zeit angeht, die dein Programm verbraucht, es klingt einfach langsam, da du nur 2,5 MByte an Daten verarbeist. Schau dir einfach mal an, in welcher Zeit ein Grafikprogramm Dateien von >> 10 MByte verarbeitet. Da werden wenige Milisekunden benötigt. Du siehst da schnell warum es langsam wirkt (muss ja nicht so sein). Gruß Der Unwissende [EDIT] Was ProcessMessages angeht, so stimmt das natürlich, was gesagt wurde. Aber Application.ProcessMessages ist ein schlechter Weg. Der Aufruf dieser Methode kostet Zeit, auch wenn mal nichts zu tun ist. Andererseits wird auf Nachrichten (wie dem neu zeichnen) nur reagiert, wenn die Windowsbotschaft dafür auch behandelt werden kann. Man muss also einen Kompromiss zwischen sehr vielen Application.ProcessMessages (sehr langsam) und sehr wenigen (seltenes Neuzeichnen) finden. Wird ein Thread mit niedrigerer Priorität verwendet, so bekommt der immer die volle Rechenzeit, die zur Verfügung steht. Muss das Fenster neu gezeichnet werden, wird die durch die Applikation höherer Priorität ausgelöst. Dieser Prozess würde dann automatisch Vorrang bekommen. Somit muss man sich keine Gedanken um die Stellen machen, an denen man ein Neuzeichnen erlauben möchte, es passiert automatisch dann und nur dann, wenn es nötig wird. [/EDIT] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 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