小弟初学delphi 一个自动上传文件同时改订单状态的程序   下面的代码是用timer调用的
当程序运行时间长了以后就会报错
那个“xxxxxx”会变的,每次不一样    in module 有时候有 有时候没procedure TForm1.downListAndUpload();
var
  i: Integer;
  j: Integer;
begin
  ListView1.Clear();
  Panel2.Visible := false;  //下载FTP上的文件列表
  if not FileExists(ExtractFilePath(Paramstr(0)) + userName + '.txt') then
  begin
    FtpLibrary1.localpath := ExtractFilePath(Paramstr(0)) + userName + '.txt';
    FtpLibrary1.remotepath := userName + '.txt';
    if FtpLibrary1.ExistFile(userName + '.txt') then
    begin
      if FtpLibrary1.Download() then
        FtpLibrary1.DeleteFile(userName + '.txt');
    end
    else
    begin
      if CheckBox3.Checked = true then
        //自动关机
        ShutDown();
    end;
  end;
  //列表存在 解析文件列表 加入listview
  if FileExists(ExtractFilePath(Paramstr(0)) + userName + '.txt') then
  begin
    mystring := TStringlist.Create;
    mystring.LoadFromFile(ExtractFilePath(Paramstr(0)) + userName + '.txt');
    list := TStringlist.Create;
    ExtractStrings(['|'], [], Pchar(mystring.text), list);
    mystring.Free;
    //增加
    for i := 0 to list.Count - 1 do
    begin
      sub := TStringlist.Create;
      ExtractStrings(['$'], [], Pchar(list[i]), sub);
      ListItem := ListView1.Items.Add;
      ListItem.Caption := StringReplace(sub[0], ' ', '', [rfReplaceAll]);  //添加标题
      ListItem.SubItems.Add(inttostr(i));
      sub.Free;
    end;    FtpLibrary1.Encoding := 'UTF8';
    FtpLibrary1.ReplaceSetting := 2;
    isUpdating := true;    //上传到服务器    for i := 0 to list.Count - 1 do
    begin
      sub := TStringlist.Create;
      ExtractStrings(['$'], [], Pchar(list[i]), sub);
      FtpLibrary1.localpath := sub[0];
      tempWide := sub[0];
      tempWide := ExtractFileName(tempWide);      FtpLibrary1.remotepath := string(tempWide);      if FtpLibrary1.Upload() then
      begin
        url := baseUrl+'/clientlogin!updateOrdersByFileName?orderCode='
          + sub[1];
        Idhttp1.HandleRedirects := true;     //必须支持重定向否则可能出错
        Idhttp1.ReadTimeout := 5000;         //超过这个时间则不再访问
        try
          s := Idhttp1.Get(url);
        except
          url := baseUrl1+'/clientlogin!updateOrdersByFileName?orderCode='
          + sub[1];
          try
            s := Idhttp1.Get(url);
          except
            s := 'fail';
          end;
        end;        for j := 0 to listview1.Items.Count - 1 do
        begin
          if SameText(ListView1.Items[j].Caption,sub[0]) then
          begin
            ListView1.Items.Delete(j);
          Break;
          end;
        end
      end
      else
      begin
        for j := 0 to listview1.Items.Count - 1 do
        begin
          if SameText(ListView1.Items[j].Caption,sub[0]) then
            ListView1.Items.Delete(j);
          Break;
        end;
      end;
    end;
    list.Free;
    sub.Free;
    isUpdating := false;
    Panel2.Visible := true;
    //上传完删除文件列表
    sleep(1000);
    DeleteFile(ExtractFilePath(Paramstr(0)) + userName + '.txt');
  end;
  Timer1.Enabled := true;
end;

解决方案 »

  1.   

    顶一下先  那个ftplibrary1 是第三方控件
      

  2.   

    你的问题说明的还是不清楚,不确定问题是不是在这里。
    一般有删除的情况下,循环都是从高到低的,否则,就会出现数据溢出的,比如:本来是10条,你删除1条,剩9条,你的循环还去找第10条,肯定会出错的。        for j := 0 to listview1.Items.Count - 1 do//应改为for j := listview1.Items.Count - 1 to 0
            begin
              if SameText(ListView1.Items[j].Caption,sub[0]) then
                ListView1.Items.Delete(j);
              Break;
            end;
      

  3.   

    不好意思 ,for 向下循环用 downto :for j := listview1.Items.Count - 1 downto 0
      

  4.   

    可能是上一个Timer没有执行结束,后一下Timer已经开始了,所以会出现访问公共变量/控件的值时发生冲突了
    Timer1执行了应该设置Enabled := flase;
    downListAndUpload执行结束后再设置Enabled := true;
      

  5.   

    1    for i := 0 to list.Count - 1 do
        begin
          sub := TStringlist.Create;
          ExtractStrings(['$'], [], Pchar(list[i]), sub);
          ListItem := ListView1.Items.Add;
          ListItem.Caption := StringReplace(sub[0], ' ', '', [rfReplaceAll]);  //添加标题
          ListItem.SubItems.Add(inttostr(i));
          sub.Free;
        end;
    这里频繁的创建TStringlist然后释放,如果不是多线程程序,建议弄个全局的每次清空即可2 倒序删除listview1中的项目,你这样写会有问题的
    for j := 0 to listview1.Items.Count - 1 do
            begin
              if SameText(ListView1.Items[j].Caption,sub[0]) then
              begin
                ListView1.Items.Delete(j);
              Break;
              end;
            end3    for i := 0 to list.Count - 1 do
        begin
          sub := TStringlist.Create;
    这句sub := TStringlist.Create;是在for里创建,for循环外释放的,会内存泄漏
      

  6.   

    要删除ListView1符合记录的1笔还是删除全部,删除全部要从高到低删除
    还有看看Break是否放错地方了;