代码如下:procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
var
 item:TListItem;
 strIp:string;
 aDate,aTime:TDateTime;
 aDateTime:string;
 nIndex:integer;
begin
  strIp:=AThread.Connection.Socket.Binding.PeerIP;
  //ShowMessage(strIp);
  listView1.Canvas.Lock;
  try
  nIndex:=SeekListViewByIp(strIp);
  if nIndex=-1 then
  begin
    item:=listView1.Items.Add;
    item.Caption:=strIp;
    aTime:=Time();
    aDate:=Date();
    aDateTime:=DateToStr(aDate)+' '+TimeToStr(aTime);
    item.SubItems.Add(aDateTime);
    item.SubItems.Add(aDateTime);
  end;
  finally
  listView1.Canvas.Unlock;
  end;
end;当运行至item.caption:=strIP时,程序停止响应,搞不明白是怎么回事?

解决方案 »

  1.   

    你把加载IP到ListView的程序写成一个过程procedure AddListItem(strIp : string),然后在每次connect的时候创建一个多线程对象(自己创建一个多线程类),然后在多线程的重载excute的时间里面用synchronize访问这个过程synchronize(AddListItem).
      

  2.   

    会不会是 listView1.Canvas.Lock 的问题?
      

  3.   

    大小迷糊 说得确实可以,不过都没有告诉人家怎么回事情,我也遇到这样的问题,这是多线程与VCL之间引起,具体是什么原因,本人还是不知道,不过希望告诉,告知
      

  4.   

    不需要listView1.Canvas.Lock和listView1.Canvas.Unlock;
    多线程访问VCL可以用临界区或互斥量来解决。例如:procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
    var
     item:TListItem;
     strIp:string;
     aDate,aTime:TDateTime;
     aDateTime:string;
     nIndex:integer;
    begin
      strIp:=AThread.Connection.Socket.Binding.PeerIP;
      //ShowMessage(strIp);
      EnterCriticalSection(cs);
      try
      nIndex:=SeekListViewByIp(strIp);
      if nIndex=-1 then
      begin
        item:=listView1.Items.Add;
        item.Caption:=strIp;
        aTime:=Time();
        aDate:=Date();
        aDateTime:=DateToStr(aDate)+' '+TimeToStr(aTime);
        item.SubItems.Add(aDateTime);
        item.SubItems.Add(aDateTime);
      end;
      finally
      LeaveCriticalSection(Cs);
      end;
    end;其中:
    Cs : TRTLCriticalSection;//描述临界区信息的数据结构
    注意Cs的建立和销毁,详细可以查看相关资料。