根据LISTVIEW的内容实现多线程下载,我这样写行吗?为什么出错啊?
LISTVIEW的第一列是ID,第二列是文件名,第三列是URL
procedure   tform1.DownloadProgress1(Sender:   TDownLoadURL;   Progress,
      ProgressMax:   Cardinal;   StatusCode:   TURLDownloadStatus;
      StatusText:   String;   var   Cancel:   Boolean);
  var
  x:integer;
  i,j:integer;
  begin
  if (progressmax<>0) and (progress<>0) then begin
  x :=round((progress/progressMax)*100);
  EnterCriticalSection(CriticalSection);    for i:=0 to ListView1.Items.Count-1 do begin
     if ListView1.Items[i].SubItems.Strings[1]=StatusText then
     j:=i;
  end;
 ListView1.Items[j].SubItems.Strings[2]:=inttostr(x);
  LeaveCriticalSection(CriticalSection);
      end;
  end;procedure tform1.down1(id:pchar);
var
DownLoadURL : TDownLoadURL;
begin
DownLoadURL   :=   TDownLoadURL.Create(self);
EnterCriticalSection(CriticalSection);
      with   DownLoadURL   do
      begin
          FileName   :=   'c:\p.rar'+id;
          URL   := ListView1.Items[strtoint(id)-1].SubItems.Strings[1];
          OnDownloadProgress   :=   DownloadProgress1;
      end;
LeaveCriticalSection(CriticalSection);
DownLoadURL.ExecuteTarget(DownLoadURL);
end;procedure down2(id:pchar);
begin
form1.down1(id);
end;procedure TForm1.Button3Click(Sender: TObject);
var
ThreadID: THandle;
id:string;
i:integer;
begin
InitializeCriticalSection(CriticalSection);
  for i:=1 to ListView1.Items.Count do begin
    CreateThread(nil, 0, @down2, strnew(pchar(inttostr(i))), 0, ThreadID) ;
  end;

解决方案 »

  1.   

    它直接就出错了,TDOWNLOADURL只能在TFORM中
    只能又添了个全局的函数down2(id:pchar)
    调用 tform1.down1(id:pchar) 
    然后在createthread中再调用down2,这样写对吗?
      

  2.   

    我试了一下在下面的线程函数中出错了,不能在线程函数中调用窗体的过程吗procedure down2(id:pchar); 
    begin 
    form1.down1(id); 
    end; 
      

  3.   

    更新LISTVIEW中的下载进度时,有没好的办法知道更新的是哪一行???
      

  4.   

    这样的代码并没有达到并行下载的目的!
    在执行Down函数时就并变串行了,即使并行的线程也要等待一个线程执行完down后方可执行!
    个人认为应该这样:
    每一个线程指定自己的工作范围
    即线程1负责处理Listview中的1-4条URL
    线程2负责处理Listview中的5-8条URL
    这样就不用为Listview加锁了!也就避免了并变串的转换!
      

  5.   

    能实现同时下载,但是过一会就出错了,而且速度很慢,都是使用LISTVIEW,使用不同的列就可以不冲突了?哪有现成的例子啊?就是根据LISTVIEW同时下载的?
      

  6.   

    这样创建 DownloadURL 就不用在 TFORM中了
    DownLoadURL  :=  TDownLoadURL.Create(form1); 或 TDownLoadURL.Create(nil); 
    EnterCriticalSection(CriticalSection); 
          with  DownLoadURL  do 
          begin 
              FileName  :=  'c:\p.rar'+id; 
              URL  := form1.ListView1.Items[strtoint(id)-1].SubItems.Strings[1]; 
              OnDownloadProgress  :=  form1.DownloadProgress1; 
          end; 
    LeaveCriticalSection(CriticalSection); 
    DownLoadURL.ExecuteTarget(DownLoadURL);但是在 OnDownloadProgess 中要操作主线程中的界面控件,就需要用 Synchronize 来执行了。 
    procedure  tform1.DownloadProgress1(Sender:  TDownLoadURL;  Progress, 
          ProgressMax:  Cardinal;  StatusCode:  TURLDownloadStatus; 
          StatusText:  String;  var  Cancel:  Boolean);
    begin
       Synchronize(process)
    end;
    procedure process();
      var 
      x:integer; 
      i,j:integer; 
      begin 
      if (progressmax <>0) and (progress <>0) then begin 
      x :=round((progress/progressMax)*100); 
      EnterCriticalSection(CriticalSection);     for i:=0 to form1.ListView1.Items.Count-1 do begin 
        if form1.ListView1.Items[i].SubItems.Strings[1]=StatusText then 
        j:=i; 
      end; 
    form1.ListView1.Items[j].SubItems.Strings[2]:=inttostr(x); 
      LeaveCriticalSection(CriticalSection); 
          end; 
      end;