delphi子线程向主线程发送消息,主线程使用VCL控件显示的问题。

shengyang1980 2008-08-27 09:19:23
最近刚接触Delphi多线程,写代码时遇到了一个问题,请教高手!
我想实现的是,一个主线程负责GUI部分,两个子线程负责数据处理部分,子线程处理完毕后,发送同一个消息给主线程,消息通过WParam和LParam来区分,主线程开始在Tchart控件上绘制,完毕后等待下一次的消息,这个消息是在一个死循环中不断发送的,所以TChart控件会不断重绘,直到有结束标志,才会停止。两个子线程分别在两个TChart控件上绘图,处理结果分别在两个TChart控件上以波形显示出来。
出现的问题是,开始时两个线程都跑了,并且两个TChart都能显示并且重绘,可是过一会,大概20秒后,显示第一个线程数据的TChart控件停止重绘了,第二个TChart控件还能继续重绘,实在不知道为什么???
下面是代码的精简部分:
{*全局变量和函数声明*}
function ManageData(card_number:smallint;gnADChn:Word;gnCount:Integer;gain:Smallint;gnbuffer:array of word):boolean; //数据处理函数,供两个子线程调用
gnbufferX,gnbufferX1: array of Word ; //两个子线程存放处理后数据的存储区
Const WM_MYMESSAGE = WM_USER+1000;

{*子线程的执行部分*}
procedure MyThread.Execute;
begin
Repeat
ManageData(card_number,gnADChn,gnCount,gain,gnbuffer); //调用ManageData来处理数据.
application.ProcessMessages;
Until stop_flag;
end;

{*数据处理函数定义*}
function ManageData(card_number:smallint;gnADChn:Word;gnCount:Integer;gain:Smallint;gnbuffer:array of word):boolean;
begin
SetLength(gnbufferX,1024); //开辟存储区大小.
SetLength(gnbufferX1,1024);
if card_number = 1 then
begin
For i:=0 to 1023 do
begin
gnbufferX[i] := gnbuffer[i*(gnADChn+1)*2+k*2];
end;
PostMessage(Form1.Handle, WM_MYMESSAGE,0,card_number); //如果线程1处理完毕,发送消息到主线程
end;
if card_number = 0 then
begin
For i:=0 to 1023 do
begin
gnbufferX1[i] := gnbuffer[i*(gnADChn+1)*2+(k-16)*2];
end;
PostMessage(Form1.Handle, WM_MYMESSAGE,1,card_number); //如果线程2处理完毕,发送消息到主线程
end;
result := true;
end;

{*主线程中消息响应部分*}
procedure TForm1.OnWM_MYMESSAGE(var MSG:TMessage);
begin
if MSG.LParam = 1 then //通过LParam来区分显示哪块存储区
begin
Form1.Showdata(MSG.WParam,15,512*8,1,gnbufferX);
end;
if MSG.LParam = 0 then
begin
Form1.Showdata(MSG.WParam,15,512*8,1,gnbufferX1);
end;
end;

{*主线程中显示部分,涉及到TChart控件*}
procedure Tform1.ShowData(x:Integer;gnADChn:Word;gnCount:Integer;gain:Smallint;gnbuffer:array of word);
var
i:Integer;
chart :array of Tchart;
Showgnbuffer: array of Integer;
Begin
setlength(chart,2) ;
chart[0]:=chart1;
chart[1]:=chart2;

SetLength(Showgnbuffer,1023);
Chart[x].Series[0].Clear;
For i:=0 to 1023 do
begin
if gnbuffer[i]>32767 then
begin
Showgnbuffer[i]:=(gnbuffer[i]-65536) //数组由word型变成intger型
end
else
begin
Showgnbuffer[i]:=gnbuffer[i];
end;
Chart[x].Series[0].AddXY(i,(Showgnbuffer[i])*10/(32768*gain),'',clblue);
end;
end;

...全文
301 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
liangpei2008 2008-08-27
  • 打赏
  • 举报
回复
1.把ManageData做线程保护
2.SendMessage(Form1.Handle, WM_MYMESSAGE,0,card_number);

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧