楼主的问题很有必要用多线程。。因为取网页源码需要等待一定的时间,不可能让整个程序一起等。。因此多线程很有必要。 方法是: 你的URL总数为N,你的线程数为X,那么 N DIV X = Y 余数为Z 第一个线程负责表中第一条到第Y条, 第二个线程负责表中第Y+1条到第Y*2条, ... ... 如果Z大于0最后一个线程负责剩下的记录为方便选出这些记录交由线程去检查,可以在表中加一个整型字段,从1开始累加。下面是我写的一个过程,参数是要启动的线程个数,procedure TMain_F.GetPriceThread(ThreadCount: Integer); var I,N,X,M: Integer; ERR : string; begin I := CheckLic(1,ERR); if I <> 0 then begin Application.MessageBox(PAnsiChar(ERR), '错误', MB_OK + MB_ICONWARNING + MB_TOPMOST); Exit; end; btnGetPrice.Enabled := False; btnGetPrice3.Enabled := False; btnGetPrice5.Enabled := False; btnGetPrice10.Enabled := False; btnGetPrice30.Enabled := False; btnGetPrice50.Enabled := False; btnStopGetPrice.Enabled := True; qryTemp.SQL.Text := 'SELECT MAX(ServerID) AS MaxID FROM SERVERLIST'; if rbLoseServerGetPrice.Checked then begin qryTemp.SQL.Text := qryTemp.SQL.Text + ' where LastTime=''采集失败'''; end; qryTemp.Open; N := qryTemp.FieldByName('MaxID').AsInteger; X := N div ThreadCount; M := N mod ThreadCount; for I := 1 to ThreadCount do begin if not rbLoseServerGetPrice.Checked then begin ThGetPriceX.Create('ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X)); end else begin ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X)); end; Delay(500); end; btnStopGetPrice.Tag := ThreadCount; if M > 0 then begin if not rbLoseServerGetPrice.Checked then begin ThGetPriceX.Create('ServerID>' + IntToStr(ThreadCount*X)); end else begin ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>' + IntToStr(ThreadCount*X)); end; btnStopGetPrice.Tag := btnStopGetPrice.Tag + 1; end; end;
这些是重点部份procedure TMain_F.GetPriceThread(ThreadCount: Integer); var I,N,X,M: Integer; ERR : string; begin qryTemp.SQL.Text := 'SELECT MAX(ServerID) AS MaxID FROM SERVERLIST'; if rbLoseServerGetPrice.Checked then begin qryTemp.SQL.Text := qryTemp.SQL.Text + ' where LastTime=''采集失败'''; end; qryTemp.Open; N := qryTemp.FieldByName('MaxID').AsInteger; X := N div ThreadCount; M := N mod ThreadCount; for I := 1 to ThreadCount do begin if not rbLoseServerGetPrice.Checked then begin ThGetPriceX.Create('ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X)); end else begin ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X)); end; Delay(500); end; btnStopGetPrice.Tag := ThreadCount; if M > 0 then begin if not rbLoseServerGetPrice.Checked then begin ThGetPriceX.Create('ServerID>' + IntToStr(ThreadCount*X)); end else begin ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>' + IntToStr(ThreadCount*X)); end; btnStopGetPrice.Tag := btnStopGetPrice.Tag + 1; end; end;
通讯给主线程发消息就行 , 如果用的是VCL封装的TThread类, 用它的 Synchronize方法就好了, 其实也是个消息+ 事件做的同步创建线程,你的每条数据都有ID, 你在主线程或者自己写的线程管理类中,给其分配指定的线程去查的范围
参数自己重写TThread类, 把ID传进去,也可以一次全查出来,把数据分块给工作线程
方法是:
你的URL总数为N,你的线程数为X,那么
N DIV X = Y 余数为Z
第一个线程负责表中第一条到第Y条,
第二个线程负责表中第Y+1条到第Y*2条,
... ...
如果Z大于0最后一个线程负责剩下的记录为方便选出这些记录交由线程去检查,可以在表中加一个整型字段,从1开始累加。下面是我写的一个过程,参数是要启动的线程个数,procedure TMain_F.GetPriceThread(ThreadCount: Integer);
var
I,N,X,M: Integer;
ERR : string;
begin
I := CheckLic(1,ERR);
if I <> 0 then
begin
Application.MessageBox(PAnsiChar(ERR), '错误', MB_OK + MB_ICONWARNING + MB_TOPMOST);
Exit;
end; btnGetPrice.Enabled := False;
btnGetPrice3.Enabled := False;
btnGetPrice5.Enabled := False;
btnGetPrice10.Enabled := False;
btnGetPrice30.Enabled := False;
btnGetPrice50.Enabled := False;
btnStopGetPrice.Enabled := True; qryTemp.SQL.Text := 'SELECT MAX(ServerID) AS MaxID FROM SERVERLIST';
if rbLoseServerGetPrice.Checked then
begin
qryTemp.SQL.Text := qryTemp.SQL.Text + ' where LastTime=''采集失败''';
end;
qryTemp.Open;
N := qryTemp.FieldByName('MaxID').AsInteger;
X := N div ThreadCount;
M := N mod ThreadCount;
for I := 1 to ThreadCount do
begin
if not rbLoseServerGetPrice.Checked then
begin
ThGetPriceX.Create('ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X));
end else
begin
ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X));
end;
Delay(500);
end;
btnStopGetPrice.Tag := ThreadCount;
if M > 0 then
begin
if not rbLoseServerGetPrice.Checked then
begin
ThGetPriceX.Create('ServerID>' + IntToStr(ThreadCount*X));
end else
begin
ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>' + IntToStr(ThreadCount*X));
end; btnStopGetPrice.Tag := btnStopGetPrice.Tag + 1;
end;
end;
var
I,N,X,M: Integer;
ERR : string;
begin
qryTemp.SQL.Text := 'SELECT MAX(ServerID) AS MaxID FROM SERVERLIST';
if rbLoseServerGetPrice.Checked then
begin
qryTemp.SQL.Text := qryTemp.SQL.Text + ' where LastTime=''采集失败''';
end;
qryTemp.Open;
N := qryTemp.FieldByName('MaxID').AsInteger;
X := N div ThreadCount;
M := N mod ThreadCount;
for I := 1 to ThreadCount do
begin
if not rbLoseServerGetPrice.Checked then
begin
ThGetPriceX.Create('ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X));
end else
begin
ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>=' + IntToStr( (I-1) * X + 1 ) + ' AND ServerID <=' + IntToStr(I * X));
end;
Delay(500);
end;
btnStopGetPrice.Tag := ThreadCount;
if M > 0 then
begin
if not rbLoseServerGetPrice.Checked then
begin
ThGetPriceX.Create('ServerID>' + IntToStr(ThreadCount*X));
end else
begin
ThGetPriceX.Create('LastTime=''采集失败'' and ServerID>' + IntToStr(ThreadCount*X));
end; btnStopGetPrice.Tag := btnStopGetPrice.Tag + 1;
end;
end;