![]() |
Freeze bei SHFileOperationA
Hallochen,
ich benutze folgende Routine, um Dateioperationen auszuführen:
Delphi-Quellcode:
Unter anderem auch, um Dateien von einem ort an einen anderen zu kopieren... Wenn die Datei jedoch etwas größer ist (ca. 500MB), dann friert mein Programm ein (Es beruhigt sich zwar nach einer Weile, aber das dauert...). Die Routine in einen Thread auszulagern, scheint nicht wirklich sinnvoll, da überwiegend kleinere Dateien kopiert werden und da gibt es ja keine Probleme. Aber es gibt immer wieder auch mal größere dateien, die damit kopiert werden sollen...
function TMain.DoFileWork(aOperation: FILEOP_FLAGS; aFrom, aTo: AnsiString;
Flags: FILEOP_FLAGS): Integer; var FromPath, ToPath: AnsiString; SH: TSHFileOpStruct; begin FromPath := aFrom + #0#0; ToPath := aTo + #0#0; with SH do begin Wnd := 0; wFunc := aOperation; pFrom := PAnsiChar(FromPath); if ToPath <> '' then begin pTo := PAnsiChar(ToPath) end else begin // target available pTo := nil; end; // target not available fFlags := Flags; SH.lpszProgressTitle := PChar('Verschiebe...'); //funktioniert nur bei FOF_SIMPLEPROGRESS end; // structure Result := SHFileOperationA(SH); end; Hat jemand einen Tipp oder Trick für mich, was ich tun könnte, damit mein programm nicht einfriert? Oder ist die einzige Möglichkeit ein Thread? Und falls nur ein Thread in Frage kommt, "schadet" dss bei kleinen Dateien? Tausend Dank, liebe Grüße, Gina. |
Re: Freeze bei SHFileOperationA
Kuck dir deinen Code an: Keine Schleifen, nix was wiederholt wird, innerhalb deines Codes. Also hast du auch keine Möglichkeit, da per Application.ProcessMessages o.ä. was zu regeln. Bleibt also der Thread.
Was ist so schlimm daran, einen Thread einzusetzen? Auf deinem System dürften ein paar Hundert laufen, da kommts auf einen mehr auch nicht an ;) Eine Animation, wie der Explorer sie beim Kopieren zeigt, dürfte weit mehr Zyklen beanspruchen als der Overhead durch den Thread verursacht. |
Re: Freeze bei SHFileOperationA
Kleiner Tip: Nur einen Thread verwenden. Nicht immer wieder neu einen Thread erstellen!!!
|
Re: Freeze bei SHFileOperationA
Nun seid doch nicht so streng zu mir... ;)
Dateien kopieren... das kommt doch mit Sicherheit ziemlich oft vor. Und ich kann mir beim besten Willen nicht vorstellen, dass hier alle mit Threads arbeiten. Nicht dass ich was gegen Threads habe, aber ich finde es in diesem Zusammenhang einfach unnötig, oder? Wie kopiert ihr denn Dateien? Liegt es an der Routine selbst? Dann tausche ich sie eben aus, kein Problem. Was könnt ihr mir denn da empfehlen? Tausend Dank, Gina. |
Re: Freeze bei SHFileOperationA
Huch :shock: war ich zu streng? Ich sollte wohl umlernen auf Domino(-Stein) - so heißt das dann doch, oder? :mrgreen:
Ich gehe davon aus, daß es an der Routine liegt. Wenn mich nicht alles täuscht, ist das doch jene API mit der man diesen tollen Fortschrittsdialog bekommt?! Richtig? Ich denke mal, daß für dessen Anzeige ja auch Berechnungen passieren - und jeder wird sicherlich schon das eine oder andere Mal Explorer während des Kopierens übers Netzwerk (o.ä.) mit ebendiesem Dialog gesehen haben. Es ist also an sich nichts ungewöhnliches. Und nein, prinzipiell brauchst du keine Threads. Aber wenn du garantieren willst, daß dein Programm trotz Anzeige dieses Dialogs noch benutzbar bleibt, wirst du vermutlich nicht um Threads herumkommen. In diesem Fall ginge das ja auch relativ bequem über die TThread-Klasse (bzw. Derivate). ... es sei denn etwas anderes spricht gegen die Verwendung einer von TThread abgeleiteten Klasse ;) Mein obiger Tip sollte nur dazu dienen, daß du denselben Thread immer wiederverwendest. Das minimiert einen von dir befürchteten Overhead auf's nötigste :zwinker: |
Re: Freeze bei SHFileOperationA
Zitat:
@Olli: Ja, das ist die Routine. |
Re: Freeze bei SHFileOperationA
Zitat:
Um ehrlich zu sein wollte ich auf diesen Aspekt lieber nicht eingehen. Normalerweise sollte ja ein Kopieren auch nicht parallel geschehen (ebenso wie Verschieben), da sich bei der Nachfolgeoperation ja schon wieder etwas geändert haben kann. Übrigens, @Gina, jeder Thread hat quasi seine eigene Eingabeschleife. Nur aus diesem Grund ist das sinnvoll. Application.ProcessMessages() wird zwar oft als Wundermittel angepriesen, macht aber z.B. einen sonst modalen Dialog auch nicht modeless. Vielmehr wird nur garantiert, daß Knöpfchendrücken u.ä. auch notfalls während einer laufenden Aktion bearbeitet wird. An sich ist dies aber der falsche Ansatz. |
Re: Freeze bei SHFileOperationA
Hallochen,
also... in diesem speziellen Fall brauch ich die Anzeige des Fortschrittsfensters auch gar nicht. Hab halt die Routine benutzt, weil ich sie an anderen Stellen auch verwende und sie somit ja schon im Projekt integriert ist... Benutzbar sein muss mein Programm auch nicht, aber es hängt sich eben auf und ich mag es nicht, wenn man dann switchen will um mal eben ein anderes Fenster anzuschauen und nix geht mehr. Außerdem wird die eigentliche Ausführung auch noch verlangsamt. Es soll eben einfach nur seine Arbeit machen und das möglicht schnell ;) Das Ganze in einen Thread auszulagern dürfte ja kein Problem sein, aber ich befürchte eben, dass dies nach hinten los geht. Stellt Euch mal vor: In einer Liste befinden sich etliche Dateien und Ordner. Die Liste wird in einer Schleife abgearbeitet, und für jeden Eintrag wird die Kopieren-Routine aufgerufen... Das mag ja nicht so wild sein, wenn es größere Dateien sind, aber was passiert, wenn das etliche kleine Dateien von ein paar KB sind? Das geht doch ruck zuck. Da ist er doch nur noch damit beschäftigt, sich um den Thread zu kümmern, oder? Ob das so gut ist? :gruebel: Ich will ja schließlich nicht mit Kanonen auf Obstfliegen schießen... ;) Wenn ich im Explorer eine Datei kopiere, was ja im Grunde etwa die gleiche Routine sein müßte, dann kann ich doch auch derweil andere Fenster aufrufen und tun und machen. Mehr will ich eigentlich nicht... ;) LG, Gina . |
Re: Freeze bei SHFileOperationA
Wie Olli schon gersagt hat: Erstelle einen Thread und übergebe ihm alle Dateien - für jede Datei einen Thread wäre echt Overkill ;)
|
Re: Freeze bei SHFileOperationA
Erstens kannst du die Threadpriorität anpassen und zweitens verhindert der Scheduler, daß ein Thread "hungert" (so heißt das im Fachjargon).
Für mich wäre das eine typische Aufgabe, die man auslagern kann. Wenn du unbedingt den Namen der aktuellen Datei brauchst, kannst du den per Fensternachricht (SendMessage, nicht PostMessage) an dein Hauptfenster weitergeben. Ist also alles im grünen Bereich. Einzig wenn du in dem besagten Verzeichnis nebenbei was machst und es sich nicht nur um Kopieren handelt, sondern z.B. Verschieben wird es etwas kritisch. Auch beim Kopieren solltest du womöglich ausschließen, daß sich zwei Kopieraufträge in die Quere kommen, falls du mehrere erlaubst. Zitat:
PS: War das wieder zu streng? :mrgreen: ... sonst muß ich noch üben. :stupid: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07: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