我希望能够让多个线程在单个TStringList
上运行。这是我使用单个线程完成工作的当前线程代码;
type
TFilterThread = class(TThread)
protected
procedure Execute; override;
public
lCombos : TStringList;
//Public Vars
end;
procedure TFilterThread.Execute;
var
I: integer;
HTML: String;
frm1 : TForm1;
splitLogin: TStringList;
validCount: Integer;
begin
validCount := 0;
for I := 0 to lCombos.Count - 1 do
begin
if Terminated then Exit();
Unit1.Form1.ListBox1.ItemIndex := i;
try
HTML := Unit1.Form1.IdHTTP1.Get(EmailCheckURL + lCombos[i]);
if AnsiPos('You indicated you', HTML) > 0 then
begin
//Do stuff
end;
except
Continue;
end;
end;
Showmessage('Finished!');
Unit1.Form1.Button1.Caption := 'Start';
end;
启动我使用的主题;
lComboLsit := TStringList.Create;
for I := 0 to listBox1.Items.Count -1 do
lComboLsit.Add(listBox1.Items[i]);`
iTFilterThread := TFilterThread.Create(True);
iTFilterThread.FreeOnTerminate := True;
iTFilterThread.lCombos := lComboLsit;
iTFilterThread.Start;
我如何引入另一个线程来处理lCombos
列表,以便更快地完成操作?
答案 0 :(得分:3)
答案是,这取决于。如果没有修改字符串列表,那么就无所事事了。如果修改了字符串列表,那么最好的方法主要取决于您的具体用法。
查看代码,您的程序可能不受CPU限制,因此添加更多线程可能无济于事。您的程序的瓶颈将是HTTP通信。但是,尽管不受CPU限制,但运行多个线程可能会减少HTTP延迟的影响。你可以通过基准来找出答案。您似乎没有修改字符串列表,因此没有种族问题需要关注。
然而,这是一个问题:
Unit1.Form1.IdHTTP1.Get(EmailCheckURL + lCombos[i]);
只要TIdHTTP
是线程安全的,那将是有效的,并且是线程安全的。但允许线程访问类似表单上的组件是非常难看的。我没有看到任何真正的意义或需要在线程之间共享TIdHTTP
实例。让每个线程实例化并使用他们自己的TIdHTTP
组件会更加清晰。
当然,您需要决定在所有线程之间划分工作的策略。您可以拥有一个共享索引来跟踪要处理的下一个项目。让每个线程在每次采取项目时以原子方式递增它。并行for循环将非常适合这里。这可以在最新版本的Delphi中使用,也可以在任何体面的第三方并行库中使用。
您的代码确实存在一些问题。在线程过程中,您执行此操作:
Unit1.Form1.ListBox1.ItemIndex := i;
....
Unit1.Form1.Button1.Caption := 'Start';
您无法从线程访问VCL组件。
然后你这样做
ShowMessage('Finished!');
不要从线程显示UI。
成语的一点。您可以直接执行此操作,而不是循环显示列表框中的项目:
lComboLsit.Assign(listBox1.Items);