请教高手!
我写了一个多线程的程序,一个主线程,两个子线程,子线程中是数据采集卡操作函数,不停的采集,两个子线程分别对应两块采集卡。采集到一定数量的数据后,发送消息给主线程,主线程去读缓冲区,使用VCL控件TChart来实时显示,大概1秒多刷新一次。程序运行没有问题,但是当我移动程序窗口时,界面内的TChart控件立刻停止显示,程序像是死了一样。
后来上网查到了application.ProcessMessage这个方法,可是我不知道应该加在什么地方,是在子线程中呢,还是主线程中呢?

解决方案 »

  1.   

    application.ProcessMessage
    这个方法一般加到 for 循环语句中 是为了防止死循环的
      

  2.   

    应该是线程里操作了VCL控件的问题。
      

  3.   

    我的程序里都有大循环,子线程,主线程都有,是否都application.ProcessMessage呢?另外我的线程里绝对没有对控件操作,只在主线程里操作了控件。
      

  4.   

    application.ProcessMessage是一个异步操作,一般用于循环里。目的是就算进了死循环,也能触发其他事件操作,不至于程序死掉。
      

  5.   

    我想知道的是只要是大循环,就要在循环里用application.ProcessMessage么,不论是子线程内还是主线程?
      

  6.   


    当然有关系,你动了,那TChart在Refresh,而同时,线程又来操作这个TChart,那会不会有问题呢?
      

  7.   

    我的子线程绝对没有操作TChart,只是主线程在操作TChart,难道TChart的Refresh不在主线程中么?
      

  8.   

    自己写的串口操作的一个函数,供参考:
    function SendCommCmd(Command: PChar; RcvBuffer: PChar; var Len: Integer): Integer; stdcall;
    var
      i: DWord;
    begin
      if not IsActive then
      begin
        Result := ERR_SC_NOTACTIVE;
        Exit;
      end;
      if IsBusy then
      begin
        Result := ERR_SC_BUSY;
        Exit;
      end;  IsBusy := True;
      try
        Received := False;
        RcvBuf := RcvBuffer;
        BufLen := @Len;    Comm.WriteCommData(Command, Len);
        i := GetTickCount();
        while (not Received) and IsActive do
        begin
          if GetTickCount() - i >= ReadTimeout then
          begin
            Result := ERR_SC_TIMEOUT;
            Exit;
          end;
          Application.ProcessMessages;
        end;
        if not IsActive then
        begin
          Result := ERR_SC_NOTACTIVE;
          Exit;
        end;    Result := ERR_SC_SUCCESS;
      finally
        IsBusy := False;
      end;
    end;
      

  9.   

    谢谢kampan,可是我在子线程中加入了Application.ProcessMessages,结果还是一样。不知道为什么了,郁闷阿,希望大家能帮帮我。
      

  10.   

    子线程如果没做vcl的刷新,不用Application.ProcessMessages的
    这句的目的就是让程序在这个时候去取消息列表里的消息做处理,防止消息一直没被处理(如wm_paint没处理界面就死了).
    不知道楼主说的主线程是否就是应用的线程,如果是单独的线程的话,要在适当的地方加Application.ProcessMessages
      

  11.   

    我说的主线程就是应用的线程,GUI部分。为什么WM_PAINT消息没处理呢?CPU太忙了,我的程序CPU占用率在40%-60%之间。
      

  12.   

    你说的不太清楚啊.是死机还是象死机啊.如果是死机,说是说程序出错了,要重启程序才行.如果是象死机,就是说在拖动的时候TCHAR图不刷新了.按你说的实现方式应该是象死机一样,仅是在移动的时候界面不更新了,停止移动,鼠标抬起后界面又正常更新了.从业务上来说,在称动窗体的时候,上面的内容没有必要更新.所以就不用去找什么更新的办法了.
    所有的界面更新都是在主线程中完成的.而在移动的时候,主线程仅是去处理移动的效果去了.其它的绘制窗体
    的消息全都忽略掉了.
      

  13.   

    不是Application.ProcessMessages的问题,一定是线程同步上的问题。
      

  14.   

    发送消息请采用异步方式。
    不要用同步方式即可。
    同步方式是和VCL阻塞的。
    异步方式编程麻烦一点,你自己多处理一下吧,用PostMessage即可。