我希望能够使多个线程在单个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
列表上工作,以便更快地完成操作?
最佳答案
答案是,这取决于。如果未修改字符串列表,则无需执行任何操作。如果修改了字符串列表,那么最好的选择取决于您的特定用法。
查看您的代码,您的程序可能不受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);
关于multithreading - 如何使多个线程在单个TStringList上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27552481/