我的目标是在一paintbox上根据所得数据画四幅图,当按某键时数据改变,并同时开启
四条线程来计算,当计算完了后就画图显示,我是这么做的,基本功能能实现,但关闭时就出错。代码如下:
/////////线程
unit Thread_ZB;interfaceuses
  Classes,Graphics;type
  TZBThread = class(TThread)
  private
  Area : integer;
    { Private declarations }
 protected
    procedure Execute; override;
    procedure Calculat; 
   public   constructor Create(Are : Integer);
  end;
 
implementationuses NewLine;///为调用newlineform.CalculatZB(Area);
{ TZBThread }
constructor TZBThread.Create(Are : Integer);
begin
   Area := Are;
   FreeOnTerminate := True;
   inherited Create(False);
end;procedure TZBThread.Execute;
begin
  { Place thread code here }
 
         Calculat;
end;
 { TZBThread }
procedure  TZBThread.Calculat ;
begin
  newlineform.CalculatZB(Area);//根据Area值的不同计算相应图的数据
end;
end.
////////////对线程的创建
unit NewLine;
uses
  Thread_ZB;
.
.
.
var ZBThread1,ZBThread2,ZBThread3,ZBThread4 :   TZBThread;
.
.
.
procedure TNewLineForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
    VK_NEXT    : begin
                     {取得新数据代码略}
                     if ThreadsEnd then  
                     begin
                        ThreadsEnd := false;//锁住全局变量ThreadsRunning 
                        ThreadsRunning := 4;//线程数
                        ZBThread1 :=  TZBThread.Create(1);
                        ZBThread1.OnTerminate := ThreadDone;
                        ZBThread2 :=  TZBThread.Create(2);
                        ZBThread2.OnTerminate := ThreadDone;
                        ZBThread3 :=  TZBThread.Create(3);
                        ZBThread3.OnTerminate := ThreadDone;
                        ZBThread4 :=  TZBThread.Create(4);
                        ZBThread4.OnTerminate := ThreadDone;
                     end;
                 end;end;
///////////
//////
procedure TNewLineForm.ThreadDone(Sender: TObject);
begin
    Dec(ThreadsRunning);///当一个线程执行完后,线程数ThreadsRunning减一
    if ThreadsRunning = 0 then
    begin
       ThreadsEnd := true;  //打开全局变量ThreadsRunning 
       paintbox1.Refresh ;///画图显示
    end;
end;

解决方案 »

  1.   

    非法操作提示框
    还有:Runtime error 217 at 004028B0
    这种情况一般在按键一段时间不松开后出现较多
      

  2.   

    在线程的执行体中判断, 
    if Terminated then exit;
      

  3.   

    我加了
    if Terminated then exit;
    还是不行
    还有如下错误信息:
    Exception EAccessviolation in modale tt.exe at 00001DB6
    Access Violation address 00401DB6 in modale "tt.exe "
    write of address 41100000
    而且非法操作的消息框关不完
      

  4.   

    我认为问题可能在这:newlineform.CalculatZB(Area);//根据Area值的不同计算相应图的数据你按下健不起来,一下子调用了n多次keypress,并且每次都创建4个线程,每个线程结束就让计数减一,一旦有了4个结束,你就让画布刷新,可是你创建的不只是4个线程。
    出现了那个异常可能是因为多线程访问共享资源冲突问题。
    我不知道你这个函数怎么写的。
    这个函数里面你做了什么,是不是没有同步共享数据?
      

  5.   

    我加了
    if Terminated then exit;
    还是不行
    还有如下错误信息:
    Exception EAccessviolation in modale tt.exe at 00001DB6
    Access Violation address 00401DB6 in modale "tt.exe "
    write of address 41100000
    而且非法操作的消息框关不完
      

  6.   

    if Terminated then exit;
    这东西只有在线程执行函数中有循环的时候才有必要!
      

  7.   

    谢谢 stanely(俺是邢她汉子) 的回答
    我也认为错误原因就在那里。但我的确找不到具体问题所在
    我的newlineform.CalculatZB(Area);函数里只有读取全局数组是共享部分(没有数据写入)
    我对ThreadsRunning变量的处理合理吗,会有冲突吗?
      

  8.   

    我用ThreadsRunning变量应该可以所定画布吧
    我是当ThreadsRunning 为真就建立四个线程,并把ThreadsRunning值为假
    当四个线程结束时就把ThreadsRunning值为真,并刷新画布
    我这有什么问题吗?
    请各位高手帮帮想一下吧?
      

  9.   

    在TZBThread.Execute中用Synchronize(Calculat)试试看!