Какой лучший способ для этого: у меня есть txt-файл, заполненный веб-адресами, я должен проверить все из них с помощью компонента idHTTP, только простая проверка из Интернета сервер, загрузка html и поиск соответствия, я хочу, чтобы он был быстрым, есть разные типы потоков, и я не уверен, что лучше всего использовать, TParallel for
или Task threads
или обычные темы? Я пробовал до TParallel for
, и я застрял в AV, также я пробовал Task threads
, но его не быстро, HTTP-запрос становится медленнее по времени, я также пробовал обычные потоки, и я не знал, как его использовать, потому что его сложно использовать ,
примечание: Пожалуйста, НЕ спускайте вниз, мне просто нужен совет от экспертов. СпасибоКакой лучший подход сделать http-запрос
ответ
Первый совет: не используйте Indy. Использовать THTTPClient (единица System.Net.HttpClient
) - родной для Delphi XE? +
Я все еще использую старые TThreads. Я мог бы сделать предложение только с TThread.
Workflow:
Основная нить - читать ваш TXT файл построчно. После того, как строка была прочитана, вы создаете NEW thread, который загружает информацию из WWW.
Пример применения:
unit ufmMain;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Variants,
{ TThread }
System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TLoad = class(TThread)
protected
FURL,
FOutputFileName: String;
procedure Execute; override;
public
constructor Create(const AURL, AOutputFileName: String); overload;
end;
HTTP = class
public
class procedure Get(const AURL: String; out AOutputStream: TMemoryStream);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
{ THTTPClient }
System.Net.HttpClient;
procedure TForm1.Button1Click(Sender: TObject);
var
LLoad: TLoad;
LFile: TextFile;
LCycle: Integer;
LUrl: String;
begin
LCycle := 0;
AssignFile(LFile, 'urls.txt');
try
Reset(LFile);
while not Eof(LFile) do
begin
{ Using for generate file name. All file names must be unique }
Inc(LCycle);
{ Read next URL }
ReadLn(LFile, LUrl);
{ Create new thread }
LLoad := TLoad.Create(LUrl, 'Output file No ' + LCycle.ToString + '.htm');
LLoad.FreeOnTerminate := True;
LLoad.Start;
end;
finally
CloseFile(LFile);
end;
end;
{ TLoad }
constructor TLoad.Create(const AURL, AOutputFileName: String);
begin
inherited Create(True);
FURL := AURL;
FOutputFileName := AOutputFileName;
end;
procedure TLoad.Execute;
var
LResponse: TMemoryStream;
begin
inherited;
LResponse := TStringStream.Create;
try
HTTP.Get(FURL, LResponse);
{ Save result to file }
LResponse.SaveToFile(GetCurrentDir + PathDelim + FOutputFileName);
finally
LResponse.Free;
end;
end;
{ HTTP }
class procedure HTTP.Get(const AURL: String; out AOutputStream: TMemoryStream);
var
LStream: TStream;
LHTTPClient: THTTPClient;
begin
LHTTPClient := THTTPClient.Create;
try
LStream := LHTTPClient.Get(AURL).ContentStream;
AOutputStream.CopyFrom(LStream, LStream.Size);
finally
LHTTPClient.Free;
end;
end;
end.
Почему я против Инди:
1) THTTPClient не требуется дополнительных DLL для работы с протоколом SSL
2) THTTPClient современный из Delphi X Е8
3) Мое субъективное мнение: THTTPClient работает намного плавно (с меньшим количеством проблем), а затем Indy library. Я использовал Indy последние 10 лет, но теперь весь мой поддерживаемый проект переместился в THTTPClient.
Почему вы советуете использовать Indy? – mjn42
@ mjn42 - Почему я против Инди: 1) THTTPClient не требуется дополнительных DLL для работы с протоколом SSL 2) THTTPClient современный из Delphi X Е8 3) Мое субъективное мнение: THTTPClient работает гораздо более плавно (с меньше проблем), а затем Indy library. Я использовал Indy последние 10 лет, но теперь весь мой поддерживаемый проект переместился в THTTPClient. – Zam
смотрите здесь [http://stackoverflow.com/posts/comments/64687148?noredirect=1] – cyberdude
Вы можете использовать TTask и Indy (TIdHTTP). Пример:
function GetUrl(const aUrl: string): ITask;
begin
Result := TTask.Run(
procedure
var
FOutput: string;
FHTTP: TIdHTTP;
begin
FHTTP:=TIdHTTP.Create(nil);
try
try
FOutput:=FHTTP.Get(aUrl);
except
// handle errors
end;
finally
FHTTP.Free;
end;
TThread.Synchronize(nil,
procedure
begin
ProcessOutput(FOutput); // send your output/result to main thread
end);
end);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
list: TStringList;
begin
list:=TStringList.Create;
try
list.LoadFromFile('yourfile.txt');
// get all your urls
// you should control how many threads run at the same time
for i := 0 to list.Count-1 do
GetUrl(list[i]);
finally
list.Free;
end;
end;
Я полагаю, что использование ShowMessage (FOutput); 'не очень хорошая идея. – Zam
Я не думаю, что кто-нибудь будет использовать его для чтения стольких длинных источников. Это место для обработки данных. Я обновлю его для вас. – smooty86
Я использовал этот метод раньше, но этот пост-ответ становится медленнее по времени, если вы используете несколько сообщений внутри цикла – cyberdude
Что вы подразумеваете под «проверкой»? Вы имеете в виду загружать только заголовки? Проверьте, является ли он действительным URL-адресом или нет? Проверьте некоторые данные/содержимое, найденные на этом URL-адресе? Является ли ваш реальный вопрос, следует ли использовать «TParallel» или «TTask» для вашей цели? В любом случае, все эти вопросы - это широкие вопросы, которые привлекают упрямые ответы - оба из которых не одобряются здесь. что ты уже испробовал? Какие плюсы и минусы вы сами наблюдали между этими двумя возможными решениями? –
@JerryDodge Загрузка html и поиск соответствия, добавление информации. – cyberdude