Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Datei-Ladevorgang abbrechen (https://www.delphipraxis.net/198271-datei-ladevorgang-abbrechen.html)

Maekkelrajter 18. Okt 2018 22:57

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ß

DieDolly 18. Okt 2018 23:01

AW: Datei-Ladevorgang abbrechen
 
Zitat:

gibt es irgendeine Möglichkeit, programmseitig den Ladevorgang abzubrechen oder einen Timeout einzubauen?
Dazu müsste man erst wissen, wie du aktuell eine Datei einließt.

KodeZwerg 18. Okt 2018 23:10

AW: Datei-Ladevorgang abbrechen
 
Ich würde das einlesen in einen seperaten Thread verlagern und eine ProgressBar oder ähnliches als Indikator verwenden.

TigerLilly 19. Okt 2018 07:09

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?

dummzeuch 19. Okt 2018 09:22

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.

Maekkelrajter 19. Okt 2018 10:36

AW: Datei-Ladevorgang abbrechen
 
Zitat:

Zitat von TigerLilly (Beitrag 1416105)
Wie DieDolly schon fragt: Wie wird die Datei denn transferiert?

Ganz 'normal':

Delphi-Quellcode:
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;
Ob sich ein paralleler Thread 'abschießen' läßt, wage ich zu bezweifeln. Das Programm ließ sich ja nicht einmal per Taskmanager beenden.

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?

Luckie 19. Okt 2018 10:59

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.

TigerLilly 19. Okt 2018 11:16

AW: Datei-Ladevorgang abbrechen
 
Vielleicht hilft das da:

https://www.delphipraxis.net/192758-...im-thread.html

KodeZwerg 19. Okt 2018 11:23

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;

Maekkelrajter 19. Okt 2018 12:30

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 20:13 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz