我先做了一个单窗体多线程通讯程序,主线程用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.
程序全是从单窗体多线程通讯程序中复制过来的。各位,帮我看看哪儿出问题了,怎么办。
部分相关代码如下:
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.
没有办法调试你的程序,只能提出几个感觉看上去不爽的地方。。
你下面这样写线程代码,这个线程并没有起到线程的作用
(自己想想原因)procedure TDrawThread.Execute;
begin
synchronize(draw);
。
end;还有,你干嘛不让这个线程一直执行呢?
每次还要用定时器来创建?
仅仅是感觉,我认为这样处理不好。 =====哈欠====halfdream====
1.数据接收频率高,绘图不需要那么高频率,所以想到用定时器来创建。
2.用线程是因为除温度外,可能同时有其他几条线要画,防止冲突。