質問
インターネットからファイルをダウンロードしたいのですが、これは簡単な作業だと思います。いくつかの異なるアプローチを試してみると、それぞれに独自の欠点があることがわかりました。主な問題は次のとおりです。
- アプリケーションはファイルをダウンロードするまでフリーズします
- インターネット接続が失われた場合/サーバーが応答しない場合、アプリケーションは永久にフリーズします。
(詳細:
HTTP経由でインターネットからファイルを取得する方法は?
インターネットからファイルをダウンロードする際に接続がタイムアウトしません )
そこで、ついに、インディなどの「プロ」ライブラリを使用するために、数人から得た提案を使用しました。ただし、Indyは私が試したコードの部分よりもはるかに優れていません(ただし、維持するのははるかに大きくて困難です)。 Indyを使用している間、アプリケーションは短期間だけフリーズしないため、(どういうわけか)使用可能です。ただし、ダウンロードが終了するまでアプリケーションをシャットダウンすることはできません(インターネット接続が破損した場合)。
他の人々は同じ問題を報告しました: http://borland.newsgroups.archived.at/public.delphi.internet.winsock/200609/0609079112.html
https://forums.embarcadero.com/thread.jspa?threadid=25199&tstart=90
それで、それを機能させるためにTidantifreezeに私がしなければならなかったいくつかのハッキングがありますか?
また、ConnectTimeoutプロパティは認識されません。
fIDHTTP := TIDHTTP.Create(NIL);
fIDHTTP.ConnectTimeout:=5000;
インディをドロップして、ファイルを別のスレッドでダウンロードするというオリジナルのアイデアに戻り、応答しないときにスレッドを終了する必要があります(少なくともこのように、サードパーティのライブラリを削除します)?私がこれを行うと、予期せぬ副作用がありますか?
使用:Delphi 7、Indy 10.1.5 10.5(おそらく)。
ありがとう
解決
この種の問題を解決するのはそれほど難しくありません。最初にしなければならないことは、エラー処理を適切に処理していることを確認することです。何かが失敗した場合は、すべてが適切にクリーンアップすることを確認してください。それを超えて、ダウンロードコードが個別のスレッドの一部であることを確認してください。問題がある場合は、メインプログラムからいつでもスレッドを終了できます。これは、私にとって正常に動作しているコード(スレッドではなく、ダウンロードのみ)です。
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;
他のヒント
おそらく、Indy the Indy Way:Swreatsを使用する必要があります。 Indyは、ほとんどのインターネットプロトコルが機能する方法であるため、ブロッキングモードで動作するように特別に設計されていました(例:HTTPではプロトコルレベルで、リクエストを送信してから、応答を読みます。 Tidantifreezeは、スレッドを扱うことなくインディの機能を使用するのに役立つはずです。少なくとも概念的には、それは醜いハックだからです。
スレッドに対処したくない場合は、ICSをご覧ください( ICSホームページへのリンク )。 ICSは、スレッドなしで非同期モードで使用するように設計されています。ブロックしていないため、Tidantifreezeに相当するものは必要ありません。ダウンロードを開始すると、いくつかのイベントを処理して、進行状況と完了通知を取得します。 ICSは同様に有名で、プロフェッショナルで、インディと乱暴に使用されています。