2010-07-06 12 views
5

Desidero scaricare un file da Internet e immagino che questo dovrebbe essere un compito semplice. Provando diversi approcci ho scoperto che ognuno ha il suo lato negativo. I temi principali sono:La connessione non scade durante l'utilizzo di Indy

  • applicazione si blocca fino a quando si scarica il file
  • applicazione si blocca per sempre se la connessione a Internet viene persa/server non risponde.

(dettagli:

How to retrieve a file from Internet via HTTP?
The connection does not timeout while downloading file from internet)

Così, finalmente ho usato i suggerimenti che ho ricevuto da più persone di utilizzare le librerie "pro" come Indy. Comunque, Indy non è molto meglio dei pezzi di codice che ho provato (ma è molto più grande e difficile da mantenere). Durante l'utilizzo di Indy l'applicazione non si blocca solo per brevi periodi, quindi è ancora (in qualche modo) utilizzabile. Tuttavia, l'applicazione non può essere chiusa fino al termine del download (mai se le connessioni Internet vengono interrotte).

Altre persone hanno riportato lo stesso problema: http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html
https://forums.embarcadero.com/thread.jspa?threadID=25199&tstart=90

Quindi, c'è qualche violazione al sistema che ho dovuto fare per TIDAntiFreeze al fine di farlo funzionare?

Inoltre, la proprietà ConnectTimeout non viene riconosciuta.

fIDHTTP := TIDHTTP.Create(NIL); 
fIDHTTP.ConnectTimeout:=5000; 

Dovrei abbandonare Indy e tornare alla idea originale di download in un thread separato e alla fine il filo quando non risponde (almeno in questo modo mi libero di librerie 3a parte)? Ci saranno effetti collaterali imprevedibili se lo faccio?

Utilizzo: Delphi 7, Indy 10.1.5 10.5 (probabilmente).

Grazie

+2

Hai provato a utilizzare un thread per scaricare il file in background? – mjn

+2

Indy 10.1.5 è molto vecchio, la corrente è 10.5.7 – mjn

+0

La nuova versione di Indy si rifiuta di installare sul mio computer. – Ampere

risposta

1

Non è troppo difficile da risolvere questo tipo di problemi. La prima cosa che devi fare è assicurarti di aver gestito correttamente la gestione degli errori. Se qualcosa non funziona, assicurati che tutto si ripulisca correttamente. Oltre a ciò assicurati che il codice di download sia parte di un thread separato. Se c'è qualche problema puoi sempre terminare il thread dal tuo programma principale. Ecco il codice (per scaricare solo, non il threading) che sta funzionando bene per me.

with TDownloadURL.Create(nil) do 
    try 
    URL := 'myurltodownload.com'; 
    filename := 'locationtosaveto'; 
    try 
     ExecuteTarget(nil); 
    except 
     result := false; 
    end; 
    if not FileExists(filename) then 
     result := false; 
    finally 
    clear; 
    free; 
    end; 
+0

Questo non copre il punto principale di questa discussione. Citazione: "L'applicazione si blocca fino a quando non scarica il file." – Ampere

+0

Leggi di nuovo il mio post e fai anche riferimento alla risposta di Cosmin Prund. Entrambi stiamo dicendo che DEVI USARE FILETTI altrimenti non c'è modo di impedirlo. Anche con Indy è necessario utilizzare un thread, non c'è modo di aggirarlo. Hai detto che Indy era troppo ingombrante per le tue esigenze, quindi ho fornito un'alternativa testata in congiunzione con dicendo che DEVE essere infilato. Non vedo come questa risposta non copra il tuo punto principale. Risposta: infilala. – Daisetsu

+0

Risposta accettata. – Ampere

4

Probabilmente è necessario utilizzare Indy in modo Indy: utilizzando thread. Indy è stato specificamente progettato per funzionare in modalità di blocco, perché è così che funziona la maggior parte dei protocolli Internet (ad esempio: con HTTP, a livello di protocollo, si invia una richiesta, quindi si legge la risposta, non si invia e si riceve allo stesso tempo). TIdAntiFreeze dovrebbe aiutarvi a utilizzare alcune funzionalità di Indy senza occuparsi di thread; Non l'ho mai usato perché, almeno concettualmente, è un brutto scherzo.

Se non si desidera gestire Thread, è necessario dare un'occhiata a ICS (link to ICS home page). ICS è stato progettato per essere utilizzato in modalità Async, senza threading. Non ha bisogno dell'equivalente di TIdAntiFreeze perché non sta bloccando. Si avvia un download e si gestiscono alcuni eventi per ottenere le notifiche di avanzamento e completamento.ICS è altrettanto noto, professionale e sfrenato come Indy.

+0

Dopo aver girato intorno ai fili sembra che sia l'unica soluzione! Grazie. +1 – Ampere

Problemi correlati