![]() |
Datei-Ladevorgang abbrechen
Eins meiner Programme liest Daten, z. B. Textdateien oder Audiodateien ein, die sich auf einem externen PC in einem freigegebenen Ordner oder einem verbundenen Netzlaufwerk befinden können, und zwar via WLAN. Das klappt eigentlich immer problemlos. Normalerweise dauert sowas ein paar Sekunden, heute jedoch trat offenbar während der Übertragung einer Textdatei von ca. 20MB eine Störung der WLAN-Verbindung auf. Daraufhin rührte sich nichts mehr. Die Anwendung hing und ließ sich nicht mehr beenden, nicht einmal per Taskmanager. Der Rechner ließ sich auch nicht mehr herunterfahren, sondern hing beim 'Abmelden' fest. Erst als ich den als 'Server' fungierenden PC heruntergefahren hatte, ging es. Nachdem ich dann eine LAN-Vebindung via Kabel hergestellt hatte lief wieder alles reibungslos. Ich muss zugeben, dass ich von den Abläufen bei Netzwerkzugriffen so gut wie keine Ahnung habe. Bisher war das auch nicht dringend notwendig, da seit Jahren damit keinerlei Probleme auftraten.
Jetzt die Frage: gibt es irgendeine Möglichkeit, programmseitig den Ladevorgang abzubrechen oder einen Timeout einzubauen? Gruß |
AW: Datei-Ladevorgang abbrechen
Zitat:
|
AW: Datei-Ladevorgang abbrechen
Ich würde das einlesen in einen seperaten Thread verlagern und eine ProgressBar oder ähnliches als Indikator verwenden.
|
AW: Datei-Ladevorgang abbrechen
Wenn so gar nichts mehr geht, hängt/wartet eine der tieferen Protokollschichten. Wie DieDolly schon fragt: Wie wird die Datei denn transferiert?
|
AW: Datei-Ladevorgang abbrechen
Üblicherweise ist das Problem ein Fehler im Netzwerk, dabei ist es egal ob LAN oder WLAN. Beispiele: Kabel werden gezogen, Router ausgeschaltet oder der andere PC wird heruntergefahren.
Das läuft dann in die Timeouts des Netzwerk-Stacks, ohne dass der Aufrufer irgendwas dagegen tun kann, und die sind verdammt lang. Die hier vorgeschlagene Methode, die Übertragung in einen eigenen Thread auszulagern hilft bedingt. Ja, das UI reagiert dann immernoch, insbesondere auf Redraws. Aber wenn man das Programm dann beenden will, wartet Windows normalerweise darauf, dass auch dieser Thread sich selbst beendet. In wie weit es dann hilft, den Thread explizit abzuschiessen, habe ich noch nicht ausprobiert, könnte aber funktionieren. |
AW: Datei-Ladevorgang abbrechen
Zitat:
Delphi-Quellcode:
Ob sich ein paralleler Thread 'abschießen' läßt, wage ich zu bezweifeln. Das Programm ließ sich ja nicht einmal per Taskmanager beenden.
Function LoadAnsiText(FileName:String):Ansistring;
var fs:TFilestream; begin result:= ''; fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try try SetLength(result, fs.Size); fs.ReadBuffer(result[1], Length(result)); except On E:Exception do messageDlg(Format('Datei ''%s'' konnte nicht geöffnet werden.'#13#10#13#10 + '(%s:''%s'')',[fn,E.ClassName,E.Message]), mtError,[mbOK],0); end; finally fs.free; end; Eine Idee für einen Workaround: Die Datei mit SHFileOperation zunächst auf die lokale Platte kopieren. Dabei erscheint ja ein Fensterchen mit Fortschrittsbalken und einem 'Abbrechen' - Button. Damit kann man das Kopieren einer Datei abbrechen, was auch bei Netzwerk-Zugriffen zu funktionieren scheint. Vielleicht hat ja noch jemand eine bessere Idee? |
AW: Datei-Ladevorgang abbrechen
Oder eine Kopierroutine mit Callback nutzen. In der Callbackprozedur gehgbdie Komtrolle ja an den Aufrufer zurück und dort kann man dann den Kopiervorgang abbrechen. Hoffentlich. Müsste man ausprobieren.
|
AW: Datei-Ladevorgang abbrechen
|
AW: Datei-Ladevorgang abbrechen
Vielleicht über ein Mapped/Cache versuchen? So in etwa
Delphi-Quellcode:
function MMFileToString(const AFilename: string): string;
var hFile: THandle; hFileMap: THandle; hiSize: DWORD; loSize: DWORD; text: string; view: pointer; begin Result := ''; if AFilename = '' then Exit; if not FileExists(AFilename) then Exit; {Open the file} hFile := CreateFile( PChar(AFilename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); if hFile <> INVALID_HANDLE_VALUE then begin loSize := GetFileSize(hFile, @hiSize); {File was opened successfully, now map it:} hFileMap := CreateFileMapping( hFile, nil, PAGE_READONLY, hiSize, loSize, 'TextForString' ); if (hFileMap <> 0) then begin if (GetLastError() = ERROR_ALREADY_EXISTS) then begin MessageDlg( 'Mapping already exists - not created.', mtWarning, [mbOk], 0 ); CloseHandle(hFileMap) end else begin try {File mapped successfully, now map a view of the file into the address space:} view := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); if (view <> nil) then begin {View mapped successfully} {Close file handle - as long is view is open it will persist} CloseHandle(hFile); SetLength(Result, loSize); Move(view^, Result[1], loSize); end else MessageDlg( 'Unable to map view of file. ' + SysErrorMessage(GetLastError), mtWarning, [mbOk], 0 ); finally UnmapViewOfFile(view); {Close view} CloseHandle(hFileMap); {Close mapping} end end end else begin MessageDlg( 'Unable to create file mapping. ' + SysErrorMessage(GetLastError), mtWarning, [mbOk], 0 ); end; end else begin MessageDlg( 'Unable to open file. ' + SysErrorMessage(GetLastError), mtWarning, [mbOk], 0 ); end; end; |
AW: Datei-Ladevorgang abbrechen
Für die temporäre lokale Speicherung wäre ein MMF sicherlich die performanteste Lösung; Leider fehlt in dem Codebeispiel das Entscheidende, nämlich die Möglichkeit, den Kopiervorgang vom NetzLaufwerk in das MMF abbrechen zu können.
Ich fürchte, es wird auf Zwischenspeicherung in ein ein 'normales' File auf der lokalen Platte hinauslaufen. Sowas sollte mit der API-Function CopyFileEx zu bewerkstelligen sein. |
AW: Datei-Ladevorgang abbrechen
Da gibt es nichts zu fürchten. Das ist der einzige vernünftige Weg.
![]() |
AW: Datei-Ladevorgang abbrechen
Auf das MMF bezogen könnte man mit ein paar Änderungen das File Chunkweise reinladen, auf Wunsch geladenes bereits darstellen/zur Bearbeitung zur Verfügung stellen; Indikator (% Anzeige) erhöhen etc.; Knopf "Abbruch" "Retry" etc., also per Puffer kontrolliert nachladen lassen, das ganze mit einem Übertragungsdialog versehen, oder eben einen Api Kopierbefehl einleiten der das dann überträgt, wenn es gut geht (transmit OK) klappen beide Varianten. Deine Lesemethode sollte identisch schnell gegenüber dem MMF sein, ich habe es noch nicht gebencht aber mein Bauchgefühlt sagt mir ist so ziemlich das selbe nur in grün.
|
AW: Datei-Ladevorgang abbrechen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe das jetzt erstmal mit SHFileOperation gelöst, welches ja eine Fortschrittsanzeige und einen Abbruch-Button mitliefert. Passende Code-Schnipsel hatte ich noch in meiner 'Grabbelkiste'. Da ich dieses Programm voraussichtlich nur selbst und in einer bekannten Umgebung benutzen werde, wollte ich den Aufwand in Grenzen halten. Deshalb wäre es wohl Overkill, jede denkbare Konfiguration und jede Fehlermöglichkeit berücksichtigen zu wollen. Die Performance ist auch kein Problem, da es bekanntlich bei der Interaktion mit dem GUI nicht auf Nanosekunden ankommt. Der eigentliche Kopiervorgang dauert eh genausolange wie bei der direkten Methode.
Vielen Dank an alle, die mit guten Tips geholfen haben! |
AW: Datei-Ladevorgang abbrechen
Wenn ich fragen dürfte, was passiert wenn der Copy Dialog auf ist und Du das Kabel rausziehst/Verbindung trennst und was passiert wenn Dein Prozess gekillt wird bevor Copy fertig ist, die zwei Dinge Interessieren mich, Danke für Antwort darauf! (auf letzteres könnte ich mir bereits was vorstellen)
|
AW: Datei-Ladevorgang abbrechen
Im ersten Fall passiert erstmal garnichts. Der ProgressBar bleibt stehen, und das Programm wartet auf die Beendigung des Kopiervorganges und ist solange paralysiert. Das kann dauern, wie ich ja Anfangs beschrieben habe. Erst wenn ich 'Abbrechen' klicke, wird der Vorgang beendet und evtl. schon geschriebene Teile der Datei gelöscht. Anschließend ist die Anwendung wieder bedienbar, also alles ordnungsgemäß, wie es aussieht.
Wenn der Prozess 'gekillt' wird (via Taskmanager), verschwindet das Hauptfenster samt Copy-Dialog sofort. Im Taskmanager ist das Programm noch ein paar Sekunden zu sehen, wahrscheinlich bis Windows 'aufgeräumt' hat. Ich hoffe, die Fragen damit beantwortet zu haben. Gruß |
AW: Datei-Ladevorgang abbrechen
Vielen Dank fürs Feedback und ja damit ist alles gut beantwortet! :thumb:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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