这个问题常碰到,不是卡的完全不能动,还是能动,但只要timer控件一运行,整个界面对于事件和鼠标的响应明显就慢了半拍了,不知道大家在用timer控件时是怎样处理的,不让其影响事件响应,查CPU等都没有影响,不知是那里,我基本设置的是1秒到5秒,但发现和间隔大小的原因关系不大

解决方案 »

  1.   

    要看你的Timer执行了什么东西,没代码怎么知道。
      

  2.   

    以下是源代码
    procedure TMainFrm.Timer1Timer(Sender: TObject);   //此处接收数据和如果接收到就发送数据给FCS
    var
      RecMessage,Mobile,RecStr,SendStr,workNo:string;
      Fitem:Tlistitem;
    begin
      RecMessage:=self.RecMessage;
      Mobile:=copy(Recmessage,1,pos(chr(16),Recmessage)-1);
      RecStr:=copy(RecMessage,pos(chr(16),Recmessage)+1,length(RecMessage)-Pos(chr(16),Recmessage));
      WorkNo:=copy(RecMessage,Pos('#',RecMessage)+1,6);
     // statusbar1.Panels.Items[6].Text:=RecMessage;
      //开始保存接收到短信平台信息
    if length(mobile)>7 then
    begin
        with datamodule1.ADORecMess do
        begin
            close;
            sql.Clear;
            sql.Add('select * from RecMess');
            open;
            append;
            fieldbyname('RecMessMobile').AsString:=Mobile;
            fieldbyname('RecMessStr').AsString:=RecStr;
            fieldbyname('date').AsString:=datetimetostr(now);
            post;
        end;
        sendstr:=chr(2)+'3'+chr(16)+mobile+chr(16)+WorkNo+chr(16)+'1'+chr(3);
       // showmessage(RecMessage+'+'+inttostr(pos('D',RecMessage)));
        if ((pos('d',RecMessage)>3) or  (pos('D',RecMessage)>3)) and (pos('#',RecMessage)>0) then
        begin
            clientSocket1.Socket.SendText(Sendstr);  //这里解决没有加D时的发送格式问题
        end;
      //同时将信息显示到界面列表中
        Fitem:=listview3.Items.Add;
        if MainFrm.statusbar1.Panels.Items[3].Text='FCS连接成功' then
        begin
            fitem.ImageIndex:=2;
        end else
        begin
            fitem.ImageIndex:=0;
        end;
        fitem.SubItems.Add(Mobile);
        Fitem.SubItems.Add(sendstr);
        Fitem.SubItems.Add(datetimetostr(now));    //showmessage(string(sm_ID)+'s1s'+string(DestAddr)+'s2s'+string(OrgAddr)+'s3s'+string(sMsgID));
        //保存发送到FCS平台信息
        with datamodule1.ADOSendMFcs do
        begin
            close;
            sql.Clear;
            sql.Add('select * from SendMFcs');
            open;
            append;
            fieldbyname('SendMFcsMobile').AsString:=Mobile;
            fieldbyname('SendMFcsStr').AsString:=RecStr;
            if MainFrm.statusbar1.Panels.Items[3].Text='FCS连接成功'    then
            begin
                fieldbyname('SendMFcsStabus').AsString:='1';
            end else
            begin
                fieldbyname('SendMFcsStabus').AsString:='0';
            end;
            fieldbyname('date').AsString:=datetimetostr(now);
            post;
        end;
    end;
    end;
      

  3.   

    timer控件只是定时运行一段代码,这段代码还是在整个窗体的UI线程中执行的,所以会影响其它消息的响应。建议你将需要耗时较长的代码放到另一个线程中运行,空出UI主线程,自然就流畅了。
      

  4.   

    记住,timer不是现成,里面的大量运算必然会卡,改用现成,或者在循环中加入 application.postmessage
      

  5.   

    线程对于CPU占用太高,虽则不影响什么,但一看CPU占以70%以上,对于用的人来讲也不太好讲
      

  6.   

    关于里面调用RecMessage()函数的代码如下,整个timer控件涉及的代码里是没有循环的,也感觉没有太多占用运算时间的代码都比较简单。这个函数的所有代码如下
    function TMainFrm.RecMessage():string;
    var
      ret: Integer;  sm_ID: array[0..25] of char; //返回:短讯ID
      DestTON: char; //返回:目标地址号码类型
      DestNPI: char; //返回:目标地址编码方案
      DestAddr: array[0..21] of char; //返回:目标地址   接收手机号码
      OrgTON: char; //返回:源地址号码类型
      OrgNPI: char; //返回:源地址编码方案  OrgAddr: array[0..21] of char; //返回:源地址  发送手机号码  PRI: char; //返回:优先权
      RP: char;
      UDHI: char;
      PID: char; //返回:协议类型
      DCS: char; //返回:编码方案
      TimeStamp: array[0..19] of char; //返回:下发时间
      UDLen: integer;
      UserData: array[0..256] of char; //返回:用户数据
      StatusReport: byte;
      sMsgID: array[0..23] of char;
      sSubmitdate: array[0..19] of char;
      sDonedate: array[0..19] of char;
      sStatus: array[0..19] of char;
      iDeliverAckResult: Integer;
      msgid, y, m, d, h, n, dt, LocalDt: string;
      s_DestAddr, s_OrgAddr, s_TimeStamp, s_UserData, s_sSubmitdate, s_sDonedate, s_sStatus: string;
      sid, subTime, phone, msg, InsertTime: string; // Ritem,RSitem:Tlistitem;
     // sendstr:string;
    begin
       try
        fillchar(sm_ID, sizeof(sm_id), #0); //返回:短讯ID
        fillchar(DestAddr, sizeof(DestAddr), #0); //返回:目标地址
        fillchar(OrgAddr, sizeof(OrgAddr), #0); //返回:源地址
        fillchar(TimeStamp, sizeof(TimeStamp), #0); //返回:下发时间
        fillchar(UserData, sizeof(UserData), #0); //返回:用户数据
        fillchar(sMsgID, sizeof(sMsgID), #0); ;
        fillchar(sSubmitdate, sizeof(sSubmitdate), #0);
        fillchar(sDonedate, sizeof(sDonedate), #0);
        fillchar(sStatus, sizeof(sStatus), #0);
        iDeliverAckResult := 0;
        ret := MainFrm.fGetDeliverSMExEx(sm_ID, //返回:短讯ID
          @DestTON, //返回:目标地址号码类型
          @DestNPI, //返回:目标地址编码方案
          DestAddr, //返回:目标地址
          @OrgTON, //返回:源地址号码类型
          @OrgNPI, //返回:源地址编码方案
          OrgAddr, //返回:源地址
          @PRI, //返回:优先权
          @RP,
          @UDHI,
          @PID, //返回:协议类型
          @DCS, //返回:编码方案
          TimeStamp, //返回:下发时间
          @UDLen,
          UserData, //返回:用户数据
          @StatusReport,
          sMsgID,
          sSubmitdate,
          sDonedate,
          sStatus,
          iDeliverAckResult); //应答错误码
        if ret = 0 then
        begin
          s_DestAddr := Trim(DestAddr);
          s_OrgAddr := Trim(OrgAddr);
          s_TimeStamp := Trim(TimeStamp);
          s_UserData := Trim(UserData);
          s_sSubmitdate := Trim(sSubmitdate);
          s_sDonedate := Trim(sDonedate);
          s_sStatus := Trim(sStatus);      if StatusReport = 0 then  //上行信息
          begin
             result:=string(OrgAddr)+chr(16)+string(UserData);
             Mainfrm.statusbar1.Panels.Items[6].Text:=string(OrgAddr)+'#'+string(UserData);
          end else if StatusReport = 1 then //状态报告
          begin
            if Trim(sStatus) <> '' then
            begin
              msgid := trim(sMsgID);
              try
                begin
                // Memo1.Lines.Add('接收到状态报告:' + trim(sStatus));             // s^ := 'update tb_history set STSRPTTime =''' + LocalDt + ''', SP_SendTime=''' + SubTime+
                 //   ''', SP_STSRPTTime=''' + dt + ''', status=RTrim(status)+'',' + Trim(sStatus) + ''' where linkId=''' + msgid + '''';
                 // ThrdListAddPt(ExceSQLList, s);
                end;
              except
                //SysLog('接收状态报告错误 ' + e.Message);
              end;
            end;
          end
        end;
      except
          //SysLog('接收短信错误 ' + e.Message);
      end;
    end;