我写了一个线程,用来检测我们终端上面设备的工作状态.每次启动程序的时候就把这个线程起来,但线程一起来,我程序的窗口就没有响应了.如果不起线程,这个窗口是正常的.第一次用DELPHI,搞不清楚怎么回事.大家能不能帮我分析下.

解决方案 »

  1.   

    启动程序后,隔一会再启动线程看看,用一个Button测试一下。
      

  2.   

    unit UDetectCard;interface
    uses
        windows,Classes,SysUtils,Face_public,variable,forms,Dialogs;
    type
        TDetectCardThread = class(TThread)
        private
          { Private declarations }
        protected
          procedure Execute; override;
        public
          IsWorking: Boolean;
          Trantype:  Integer;
          LogFlag:   Integer;
          RetCode:   Integer;
          constructor Create;
        end;    function CreateDetectCardThread: Boolean;
        function ResumeDetectCardThread: Boolean;
        function FreeDetectCardThread: Boolean;
        function DetectCard:Boolean;
    //    function GetMagTrack(TrackData:PChar;Track2:PChar;Track3:PChar):Boolean;
    var
        DetectCardThread:TDetectCardThread;
    implementation
    uses
        processMain,udll;function CreateDetectCardThread: Boolean;
    begin
      ShowMessage('线程开启');
      Result := False;
      if ( DetectCardThread = nil ) then
      begin
        DetectCardThread := TDetectCardThread.Create;
        DetectCardThread.Execute;
        Result := True;
      end;
    end;function ResumeDetectCardThread: Boolean;
    begin
      Result := False;
      if ( DetectCardThread = nil ) then
        Exit;  DetectCardThread.Resume;
      DetectCardThread.IsWorking := true;  Result := True;
    end;function FreeDetectCardThread: Boolean;
    begin
      Result := False;
      if ( DetectCardThread = nil ) then
        Exit;  DetectCardThread.Terminate;
      while not DetectCardThread.Terminated do
        Application.ProcessMessages;  try
      if ( DetectCardThread <> nil ) then       
      begin
        DetectCardThread.Free;
        DetectCardThread := nil;
      end;  Result := True;
      except
        DetectCardThread := nil;
      end;
    end;constructor TDetectCardThread.Create;
    begin
      IsWorking := false;  inherited Create(true);  //don‘t execute
    end;procedure TDetectCardThread.Execute;
    var
        i:Integer;
    begin
          i := 0;
          while i = 0 do
          begin
            DetectCard;
          end;end;function DetectCard:Boolean;
    var
        i,Track2Pos,Track3Pos,len,ErrCount:integer;
        bReadMode,bReadTrack:BYTE;
        szTrackData:array [0..160] of char;
        szTrack2,szTrack3:string;
        PHasCard,PAllowCardIn:array [0..1] of char;begin
        ErrCount := 0;
        Result := FALSE;
        if  gComHandle = 0 then
            ErrLog(gErrLogPath,'磁条卡串口未被初始化', 5);
    //        ShowMessage('磁条卡串口未被初始化');
        PAllowCardIn[0] := char($0);
        i := CRT386_GetStatus(gComHandle,PHasCard, PAllowCardIn);
        if i = 0 then
        begin
    //        ShowMessage('读取是否有卡成功');
            if gCardState = 0 then
            begin
                if PHasCard[0] = char($1) then
                begin
    //               ShowMessage('读卡器插卡');
                   gCardState := 1;
                   i := 0;
                   i := CRT_IC_CardOpen(gComHandle);
                   if i = 0 then
                      ErrLog(gErrLogPath,'上电成功', 5);
      //                ShowMessage('上电成功');
                   i := 0;
                   i := AT88SC102_Reset(gComHandle);
                   if i = 0 then
                   begin
                      ShowMessage('复位成功');
                      ErrLog(gErrLogPath,'IC卡复位成功,判断为煤气卡', 5);
                      if(PostMessage(Controlfrm.handle,WM_MQCARD_IN,0,0))  then
                            ShowMessage('发送煤气卡消息成功');
                   end
                   else
                   begin                  i := 0;
                      bReadMode := $30;
                      bReadTrack := $35;
                      i := MC_ReadTrack(gComHandle,bReadMode,bReadTrack,szTrackData);
                      if i = 0 then
                      begin
                          Len := sizeof(szTrackData);
                                  i := 5;
                          for i:= 5 to Len-1 do
                          begin
                          if szTrackData[i] = char($1F) then
                            begin
                              Track3Pos := i;
                              break;
                            end;
                          end;                      Track2Pos := 5;
                          if szTrackData[4] = char($59) then
                          begin
                          szTrack2 := copy(String(szTrackData),6,(Track3Pos-Track2Pos));
                          end else
                          begin
                              ErrLog(gErrLogPath,'无二磁信息或读取失败', 5);
                              Inc(ErrCount);
    //                          ShowMessage('无二磁信息或读取失败');
                          end;
                          if szTrackData[Track3Pos+1] = char($59) then
                          begin
                              szTrack3 := copy(String(szTrackData),Track3Pos+3,104);
                          end else
                          begin
                              ErrLog(gErrLogPath,'无三磁信息或读取失败', 5);
                              Inc(ErrCount);
    //                          ShowMessage('无三磁信息或读取失败');
                          end;
                          if ErrCount>= 2 then
                          begin
                              PostMessage(Controlfrm.handle,WM_ReadCardFail,0,0);
    //                          ShowMessage('发送失败消息');
                          end
                          else begin
                              ShowMessage('发送成功消息');
                              if(PostMessage(Controlfrm.handle,WM_ReadCardSuccess,WPARAM(szTrack2),LPARAM(szTrack3)))  then
    //                              ShowMessage('消息发送成功');
                          end;
                          sleep(500);
    //                     ShowMessage(szTrack2);
    //                      ShowMessage(szTrack3);
                      end
                      else begin
                          ErrLog(gErrLogPath,'读取磁条卡失败', 5);
    //                      ShowMessage('读取磁条卡失败');
                      end;
                   end;
                end;// else
                //   ShowMessage('无动作1');
            end else
            begin
                if PHasCard[0] = char($1) then
    //               ShowMessage('无动作1');
                else begin
                   gCardState := 0;
    //               ShowMessage('读卡器退卡');
                end;
            end;
        end;end;
    end.
    这个是我线程的代码,窗口的代码以前别人写的,比较大,先不发了.我在程序一开始的时候就调用CreateDetectCardThread.或者在一个按钮里面开启这个线程,都会使窗口没响应了,鼠标点不到上面的按钮
      

  3.   

    线程中最好不要用ShowMessage,如果非用不可,最好是在主线程中执行,
    线程中,最好也不要用Application.ProcessMessages.
      

  4.   

    比较喜欢用  CreateThread这样子线程 与 主线程 通过 消息或其他方式来通信没啥的。
      

  5.   

    线程中涉及到窗体操作的,都要用Synchronize(yourfunc)进行同步,否则可能会造成窗体会冻结,showmessage就存在这个问题。
      

  6.   

    Execute中加上一条sleep(50);否则CPU占用率可能会狂高。
      

  7.   

    procedure TDetectCardThread.Execute;
    begin
      while not Terminated do begin
        DetectCard;
        sleep(50);
      end;
    end;
      

  8.   

    你在主线程调用Execute?
    那你这就失去线程的意义了,你这是单线程的。
      

  9.   

    还有一个问题想请教大家
    PostMessage(Controlfrm.handle,WM_ReadCardFail,0,0);
    ErrLog(gErrLogPath,'读取卡片磁条信息失败', 5);
    ShowMessage('读取失败');
    如果我把ShowMessage这句注释掉的话,PostMessage发出的消息,ControlFrm就收不到这个消息,如果ShowMessage没注释掉,ControlFrm就能收到该消息