如何使多个线程在单个TStringList上工作

时间:2014-12-18 17:36:45

标签: multithreading delphi

我希望能够让多个线程在单个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列表,以便更快地完成操作?

1 个答案:

答案 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);