线程单元代码如下:
type
  TProcessCom =class(TThread)
  private
  sSocket:TCustomWinSocket;
  lstItem:TListItem;
  sComm:Byte;
  sString:AnsiString;
  pStrList, pStrList2:TStringList;
  SocketData: TSocketData;
  protected
    procedure Execute; override;
    procedure DOSynJob;
  Public
    constructor Create(FSocket:TCustomWinsocket;FComm:Byte;FString:AnsiString);
    destructor Destroy; override;
  end;implementation
uses UnitMain;constructor TProcessCom.Create(FSocket:TCustomWinsocket;FComm:Byte;FString:AnsiString);
begin
  inherited Create(False);
  sSocket:=FSocket;
  sComm:=FComm;
  sString:=FString;
  FreeOnTerminate:=True;
  Suspended:=False;
end;destructor TProcessCom.Destroy;
begin
  inherited Destroy;
end;Function Explode(sDelimiter: string; sSource: String): TStringList;
Var
  c: Word;
Begin
  Result := TStringList.Create;
  C := 0;
  While sSource <> '' Do
  Begin
    If Pos(sDelimiter, sSource) > 0 Then
    Begin
      Result.Add(Copy(sSource, 1, Pos(sDelimiter, sSource) - 1 ));
      Delete(sSource, 1, Length(Result[c]) + Length(sDelimiter));
    End
    Else
    Begin
      Result.Add(sSource);
      sSource := ''
    End;
    Inc(c);
  End;
End;procedure TProcessCom.Execute;
var
  lstTemp:TListItem;
begin
  if sSocket.Data = nil then begin
    SocketData := TSocketData.Create;
    sSocket.Data := SocketData;
  end;
  case sComm of
    PACK_AUTH:
    begin
      pStrList := Explode('|',sString);
      if pStrList.Count <> 7 then begin
        FormMain.DisconnectSocket(sSocket);
        exit;
      end else begin
        Synchronize(dosynJob);   
      end;
    end;
  end;
  if pStrList<>nil then  pStrList.Free;end;procedure TProcessCom.DOSynJob;
var
  IpAddr:AnsiString;
begin
  IpAddr:=GetIPtoAdder(sSocket.RemoteAddress);
  lstItem:=FrameOnlineServer.OnlineLV.Items.Add;//   访问VCL就出错
  lstItem.Caption:=sSocket.RemoteAddress;  
  lstItem.SubItems.Add(string(IpAddr));              
  lstItem.SubItems.Add(pStrList[1]);                   
  lstItem.SubItems.Add(pStrList[8]);       
  lstItem.SubItems.Add(pStrList[2]);           
  lstItem.SubItems.Add(pStrList[3]);     
  lstItem.SubItems.Add(pStrList[4]);             
  lstItem.SubItems.Add(pStrList[0]);           
  lstItem.SubItems.Add('test');                    
  lstItem.SubItemImages[2]:=GetFlag(pStrList[8]);
  lstItem.SubItems.Objects[0]:=sSocket;
  lstItem.ImageIndex:=143;
  lstItem.OverlayIndex:=137;
  AddLog('添加主机成功: ' + sSocket.RemoteAddress,clBlue); 
  TSocketData(sSocket.Data).lstConnectionItem := lstitem;
  TSocketData(sSocket.Data).sUserPath := pStrList.Strings[1];
  TSocketData(sSocket.Data).sRemoteHost := sSocket.RemoteAddress;
  CountConnections;
end;end.
FrameOnlineServer在出窗体创建的时候就Create了,线程调用是在socket的Onread事件里面 TProcessCom.Create(Socket,bByte,tempStr);
调试的时候看到数据传递时没有出错的,本来这一个单元不是线程,就是直接往FrameOnlineServer添加数据,不会出错。
可我想改成线程来处理Socket接收到的数据,不知道哪里出错了,新手学delphi,各位大牛帮忙看看。

解决方案 »

  1.   

      lstItem:=FrameOnlineServer.OnlineLV.Items.Add;//   访问VCL就出错确定错误是由这行引起的? 
      

  2.   

    不是很理解你为什么要直接同步到VCL
    我用线程一般是用TStringList或着TList,然后MainForm的OnIdle事件读列表数据就行了
      

  3.   

     谢谢楼上回复,线程同步到VCL也没有啥不好的,这个程序是做服务器用的,用Onidle估计达不到要求,另我上面的线程代码哪里出了错,或者是FrameOnlineServer里面要怎么设置,还请多指教。
      

  4.   

    使用了Synchronize,访问vcl应该只会慢而不会出错啊不过,线程最好是不要主动去操作vcl,而是通过一个消息或公共变量来通知主线程,由它主动按通知内容进行vcl的修改
      

  5.   

    同样谢谢楼上回复。
    我的线程调用是在ServerSocket的Onread事件里面 TProcessCom.Create(Socket,bByte,tempStr),我设想的目的就是减轻ServerSocket的负担(不知道对不对),楼上sz_haitao大牛说“使用了Synchronize,访问vcl应该只会慢”是否有理论上的依据,如果确实如此,那我这么做岂不是画蛇添足了,另外,我还是想知道我的代码哪里出错了。
      

  6.   

    问题补充  IpAddr:=GetIPtoAdder(sSocket.RemoteAddress);
      FormMain.Caption:='test';//这里并没有出错
      lstItem:=FrameOnlineServer.OnlineLV.Items.Add;      //这里访问就出错了我尝试访问主窗体,发现并没报错,为什么访问其他Frame就出错了。
      

  7.   

    FrameOnlineServer是在主窗体的?怎么前面没有“formmain.”?
      

  8.   

    FrameOnlineServer不是主窗体里面的,是我新建的一个Frame,当然后面绑在了FormMain的一个Panel上面
    程序代码没错,错就错在同步事件里面的lstItem:=FrameOnlineServer.OnlineLV.Items.Add; 提示访问出错
      

  9.   

    是不是就是因为后绑的,导致Synchronize没把它算入主界面的?
      

  10.   

    你的 Frame的在你调用时候创建对象没? 
      

  11.   

    我的Frame在主窗体Create的时候就生成了
      

  12.   

    错误信息 大致就是Access error,反正是提示访问错误之类,代码我已经改动了,放弃了这种方式,但我还是想知道为什么同步的时候不能访问。
      

  13.   

    比较大的可能性应该还是访问到尚未被创建的对象了,主窗体点右键菜单中选择"Creation Order..."看看调整一下创建顺序。
      

  14.   

    谢谢各位的热心帮助,虽然问题没有彻底解决,但我还是学到不少东西,这个线程的功能我直接在在socket的Onread事件里面处理,在这里另生成线程确实画蛇添足。