![]() |
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:34 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