程序可以正常运行,只是界面象死掉一样。不知道问题出在哪里?
Type
  TMonitorThread=Class(TThread)
  Private
    FTerminal: string;  //设备名称
    FIndex: Integer;    //设备在TreeView中的位置
    FConnected: Boolean;//连接标识
    procedure MonitorStatus;
  Protected   
    procedure Execute;Override;   
  public   
    Constructor Create(Suspended:Boolean; terminal:string; connected:Boolean; index: Integer );
  End;
constructor TMonitorThread.Create(Suspended:Boolean; terminal:string; connected:Boolean; index: Integer);
begin
  inherited Create(Suspended);
  FTerminal:=terminal;
  FIndex:=index;
  FConnected:=false;
  FreeOnTerminate:=True;
end;procedure TMonitorThread.MonitorStatus;
var
  api: ILogicAPI;   //调用WebService的接口
  cmdstr: WideString;
  psa: PSafeArray;
  pt: Pointer;
  sRes: WideString;
begin
  cmdstr:='state@display@Display@'+FTerminal;
  api:=CreateComObject(CLASS_LogicAPI_) as ILogicAPI;
  psa:=api.Unitecommand(cmdstr);
  if psa=nil then
  begin
    FrmMain.UpdateTerminalImage(Findex,4);
    FConnected:=False;
  end
  else
  begin
    SafeArrayAccessData(psa,pt);
    sRes:=TWideStringArray(pt)[0];
    if (sRes='1') and (FConnected=True) then
    begin
      FrmMain.UpdateTerminalImage(Findex,3);
      FConnected:=True;
    end else
    if (sRes='1') and (FConnected=False) then
    begin
      cmdstr:='show@display@Display@'+FTerminal+'@'+FTerminal;
      iapi.Unitecommand(cmdstr);
      FrmMain.UpdateTerminalImage(Findex,3);
      FConnected:=True;
    end;
    SafeArrayUnAccessData(psa);
  end;
end;procedure TMonitorThread.Execute;
begin
  while not terminated do
  begin
    Sleep(10);
    Synchronize(MonitorStatus);
  end;
end;procedure TFrmMain.cbbRFIDServerChange(Sender: TObject);
var
  i: Integer;
begin
  for i:=0 to tvServer.Items.Count-1 do
  begin
    if not tvServer.Items[i].HasChildren then
    begin
      TMonitorThread.Create(False,tvServer.Items[i].Text,false,i);
    end;
  end;
end;

解决方案 »

  1.   

    调用窗口控件时,要用synchronize函数同步;
      

  2.   

    楼主已经使用了synchronize方法同步可视控件,这是正确的做法。
    建议楼主试试以下方法,
    1,在更新控件后,使用Application.ProcessMessages方法,在使用Sleep方法,应该有所改观的;
    2,在线程中,不适用循环,改用一次循环一个线程,可以使用临界区,来同步这些线程
      

  3.   

    在主程序中创建临界区变量,在每个线程内部,起始的时候,进入临界区,在线程结束时一定要退出临界区,否则将出现死锁了!建议线程的Execute方法中使用
    try
      FCriticalSection.Enter;
      
    finally
      FCriticalSection.Leave;
    end;
      

  4.   


    这种写法是有问题的当Enter失败的时候仍然会执行Leave.
      

  5.   

    多谢unsigned兄,先又遇到了一个问题。我在一个for循环里建立clientSocket,为什么它不会立即出发onread事件,我想每循环一次就触发一次onread事件
    procedure onRead(Sender: TObject; Socket: TCustomWinSocket);
        for i:=0 to lv1.Items.Count-1 do
      begin
         clientSocket:= TclientSocket.Create(nil);
        try
          clientSocket.Address:='127.0.0.1';
          clientSocket.Port:=7081;
          clientSocket.ClientType:=ctNonBlocking;
          clientSocket.OnRead:=onRead;
          clientSocket.Active:=True;
          ClientSocket.Socket.SendBuf(tempvar[0],Length(pc));
        finally
          clientSocket.Free;
        end;
      end;