Entwickler-Ecke

Internet / Netzwerk - UrlDownloadToFile - Endlosladen abbrechen


Jakane - Fr 19.04.13 09:33
Titel: UrlDownloadToFile - Endlosladen abbrechen
Hallo liebe Delphi-Helfer :)

Dank euch läuft mein Download der Versionsdatei gut, aber seit kurzem habe ich bei einer Exe ein Problem.

Normal sollte der Download, einer Textdatei mit nichtmal 10 Zeichen, recht zügig entweder ein "hat nicht geklappt" oder "hat geklappt" zurück geben.
Aber in diesem einen Fall hängt er sich in der Funktion irgendwie auf und legt mein ganzes Programm lahm :(

Try-Except hat nicht geholfen.
Das ganze in ein Thread auslagen ist mir zu kompliziert.

Hat jemand eine andere Idee?

Danke für Hilfen :)


HenryHux - Fr 19.04.13 09:50

Hat die Methode evtl. einen Timeout Wert? Das wäre wohl am einfachsten.
Ansonsten hört sich das doch nach einer guten Verwendung von Threads an, ist auch nicht so schwierig :)
Jedoch bringen dir auch Threads nichts, wenn dein Download einer so kleinen Datei so lange dauert, wenn die Funktion womöglich gar nicht klappt.
lg


Jakane - Fr 19.04.13 10:05

user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
Hat die Methode evtl. einen Timeout Wert? Das wäre wohl am einfachsten.
Ansonsten hört sich das doch nach einer guten Verwendung von Threads an, ist auch nicht so schwierig :)
Jedoch bringen dir auch Threads nichts, wenn dein Download einer so kleinen Datei so lange dauert, wenn die Funktion womöglich gar nicht klappt.
lg


Die Funktion klappt in 12/13 Fällen und im letzten Fall nur seit Montag nicht mehr.
Also liegt es daran nicht.

Und ein Thread würd ich nur ungern benutzt, die sind mir zu kompliziert :(

Am liebsten würd ich irgendwie eine Schleife machen, die das nach 10Sekunden von alleine abbricht oder so


HenryHux - Fr 19.04.13 10:41

Das kannst du nicht so ohne Weiteres machen, wenn die langen Ladezeiten wegen nur einer Funktion auftreten, denn auf die musst du dann warten. Du könntest höchstens in der Funktion selbst (UrlToFile) nachschauen ob sich da was machen lässt.


Jakane - Fr 19.04.13 10:50

ich weiss nichts mit den Funktionen anzufangen, ausser das sie meistens funktionieren :(


Quelltext
1:
2:
3:
4:
{$EXTERNALSYM URLDownloadToFile}
function URLDownloadToFile(p1: IUnknown; p2: PChar; p3: PChar; p4: DWORD; p5: IBindStatusCallback): HResult; stdcall;

function URLDownloadToFile;              external UrlMonLib name 'URLDownloadToFileA';


WasWeißDennIch - Fr 19.04.13 10:59

Wenn man das hier [http://www.delphipraxis.net/47-datei-downloaden-mit-fortschrittsanzeige.html] als Basis nimmt, dann könnte man doch einen Timer laufen lassen, der prüft, ob sich etwas getan hat (Statusänderung bzw. Daten empfangen). Falls nicht, setzt man die UserCancel-Variable und ist raus, sofern ich den Code auf die Schnelle korrekt überblickt habe.


Jakane - Fr 19.04.13 11:29

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Wenn man das hier [http://www.delphipraxis.net/47-datei-downloaden-mit-fortschrittsanzeige.html] als Basis nimmt, dann könnte man doch einen Timer laufen lassen, der prüft, ob sich etwas getan hat (Statusänderung bzw. Daten empfangen). Falls nicht, setzt man die UserCancel-Variable und ist raus, sofern ich den Code auf die Schnelle korrekt überblickt habe.


Ohne Thread gehts nicht? :-/


WasWeißDennIch - Fr 19.04.13 11:41

Wo siehst Du da einen Thread?


Jakane - Fr 19.04.13 12:35

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Wo siehst Du da einen Thread?



Quelltext
1:
2:
type
  cDownloadStatusCallback = class(TObject,IUnknown,IBindStatusCallback)


Ein Formular hätte class(TForm), ein Service hat class(TService).

class(TObject, IUnknown, IBindStatusCallback)?

3 statt 1

Auf jedenfall kein Standard, was auch immer das ist. :D


WasWeißDennIch - Fr 19.04.13 13:30

Das sind Interfaces, über die die Funktion einen Callback zur Verfügung stellt. Über diesen Callback kann man sich in die Ereignisse einklinken, um es mal salopp auszudrücken.


Jakane - Fr 19.04.13 14:37

hmm ok, die Definition hab ich verstanden.

Jetzt muss ich nur noch wissen wie und wo ich was einbauen muss/kann ^^


WasWeißDennIch - Fr 19.04.13 14:52

Ein Beispiel steht doch in dem verlinkten Artikel. Ich würde lediglich darauf verzichten, in den Callback-Routinen hartkodiert auf die globale Formularvariable zuzugreifen und stattdessen Events samt zugehöriger Handler deklarieren. Also etwa so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
type
  TFindingResourceEvent = procedure(Sender: TObject; const AMessage: stringof object;

  cDownloadStatusCallback = class(TObject,IUnknown,IBindStatusCallback)
  private
    ...
    FOnFindingResource: TFindingResourceEvent;
  public
    property OnFindingResource: TFindingResourceEvent read FOnFindingResource write FOnFindingResource;
  end;

  TForm1 = class(TForm)
    ...
  private
    procedure DoOnFindingResource(Sender: TObject; const AMessage: string);
    ...
  end;

...

  case ulStatusCode of
    BINDSTATUS_FINDINGRESOURCE:
    begin
      if Assigned(FOnFindingResource) then
        FOnFindingResource(self, 'Datei wurde gefunden...');
      if (usercancel) then
      begin
        Result := E_ABORT;
        exit;
      end;
    end;

...

procedure TForm1.DoOnFindingResource(Sender: TObject; const AMessage: string);
begin
  lblStatus.Caption := AMessage;
end;

...

cDownStatus := cDownloadStatusCallBack.Create;
cDownStatus.OnFindingResource := DoOnFindingResource;