我先做了一个单窗体多线程通讯程序,主线程用Mscomm定时收数据,一线程实现动态绘图,一线程用Socket实现局域网通讯。由按钮启动另一Timer,定时调用绘图线程,程序运行很好。后来我重做了一下,在前加了其他窗体,由窗体的OnCreate事件启动定时收数据,运行很好,加上Socket通讯线程时,运行也很好,而再加上定时调用绘图线程程序时,程序一运行,主界面出来后很快提示出错:EAccess Violation with message 'Access Violation at address 00416704 in module 'user.exe',Write of address 000000c'.'user.exe'为工程名。后来我将绘图窗体改为available form,在前一窗体由creareForm动态创建,运行时,前面很好,一旦运行至该窗体(不管是否决定调用绘图线程),界面出来后很快同样提示出错。
程序全是从单窗体多线程通讯程序中复制过来的。各位,帮我看看哪儿出问题了,怎么办。
部分相关代码如下:
procedure TForm_show.FormCreate(Sender: TObject); //窗体产生
begin
  .
  .
  .
 if Mscomm1.PortOpen=false then       {串口开通}
     begin
       Mscomm1.Commport:=1;
       Mscomm1.RThreshold:=1;
       Mscomm1.PortOpen:=True;
     end;
   Timer_Start.Enabled:=True;
   Timer_Start.Interval:=3000;
    if (Timer_WenThr.Enabled=false) and (ThrStart_Wen=1) then  {温度线程时间开关}
     begin
        Timer_WenThr.Enabled:=True;
        Timer_WenThr.Interval:= T_Interval;
     end;
   Scale_Wen:=3.5;
   Step_Wen:=Drawgrid1.DefaultColWidth+1 ;
   X2_Wen:=X0;                {中间变量}
   Y2_Wen:=Y0;
end;procedure TForm_show.Timer_WenThrTimer(Sender: TObject);  {温度线程启动}
begin
   if ThrStart_Wen=1 then
     begin
       if Length(Edit_Wen.Text)=0 then Thread_Wen.Suspend
       else
         begin
          F_Wen:=StrToFloat(Edit_Wen.Text);
           X2:=X1+Step_Wen;
           Y2:=Y0-Round(scale_Wen*F_Wen);
           X2_Wen:=X2;
           Y2_Wen:=Y2;
           X2_WenA[N_Wen]:=X2;
           Y2_WenA[N_Wen]:=Y2;
           M_Wen:=M_Wen+1;        //
           Thread_Wen:=TDrawThread.Create     (DrawGrid1,clRed,tpnormal,X1,Y1,X2,Y2);
           Thread_Wen.Resume;
         end;
     end
    else
     Thread_Wen.Terminate;
end;unit DrThread;interfaceuses
  Classes,Graphics,Grids;type
  TDrawThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
    procedure Draw;
  public
    FColor:TColor;
    FP:TThreadPriority;
    X1s,Y1s,X2s,Y2s:integer;
    FDrawGrid:TDrawGrid;
    Constructor Create(DrawGr:TDrawGrid;Col:TColor;P:TThreadPriority;X1s,Y1s,X2s,Y2s:integer);
  end;implementation
 uses show;Constructor TDrawThread.Create(drawGr:TDrawGrid;Col:TColor;P:TThreadPriority;X1s,Y1s,X2s,Y2s:integer);
begin
  FDrawGrid:=DrawGr;
  FColor:=Col;
  X1:=X1s;
  Y1:=Y1s;
  X2:=X2s;
  Y2:=Y2s;
  fp:=p;
  inherited Create(true);
  Priority:=fp;
end;procedure TDrawThread.Draw;
begin
  with FDrawGrid.canvas do
    begin
      lock;
      Pen.Color:=FColor;
      MoveTo(X1,Y1);
      LineTo(X2,Y2);
      unlock;
    end;
end;procedure TDrawThread.Execute;
begin
   synchronize(draw);
    freeonterminate:=true;
end;end.

解决方案 »

  1.   

    干嘛不在主线程中画图,新线程中处理数据的接收呢?:)
    没有办法调试你的程序,只能提出几个感觉看上去不爽的地方。。
    你下面这样写线程代码,这个线程并没有起到线程的作用
    (自己想想原因)procedure TDrawThread.Execute;
    begin
       synchronize(draw);

    end;还有,你干嘛不让这个线程一直执行呢?
    每次还要用定时器来创建?
    仅仅是感觉,我认为这样处理不好。                                        =====哈欠====halfdream====
                                          
      

  2.   

    to halfdream:
       1.数据接收频率高,绘图不需要那么高频率,所以想到用定时器来创建。
       2.用线程是因为除温度外,可能同时有其他几条线要画,防止冲突。
      

  3.   

    to senliu(翠儿) 1.数据接收频率高,绘图不需要那么高频率,所以想到用定时器来创建。  你可以在不用的时候挂起。2..用线程是因为除温度外,可能同时有其他几条线要画,防止冲突。  防止冲突要线程同步的,如果没有做线程同步的话,多线程反而要引起混乱,造成冲突。建议看《delphi5开发人员指南》关于多线程的知识,讲的比较全面。