100分再问一个关于线程的难题
我已经写好一个线程,但是还有几个说大不大,说小不小的难题。
首先,我想动态创建多个线程,但又不能都用同一个名字,因为我可能要在某些时候终止它们,假如使用以下代码:
for i:=0 to threadcount do
mythread:=tmythread.create;
的话我就无法指定操作哪个线程了,所以我采用了数组的形式
var mythread: array[0..99] of tmythread;
...
for i:=0 to threadcount do
mythread[i]:=tmythread.create;
来创建。本来这样不错,但问题也来了。
我的线程有onterminate事件,我想在调用tmythread的form里面通过这个结束事件触发一个变量加1,那样当这个变量加到和预先设定的变量threadcount相等时,就说明所有的线程都完成了,那就可以告诉用户事情干完了。但我不知道怎样在form中使用mythread的onterminate事件。而且mythread只能在form的var中定义,又不能像其它VCL控件一样在type那里定义,好象根本不可能支持事件,请问怎样解决呢?而且type也不允许定义数组啊。
另外,我还需要其它的事件,例如在线程中发现某些处理的数据有问题,要提起一个事件告诉程序这个数据出错了,那怎样写这些事件呢?
其实以上问题都是关于线程的事件的编写和调用的,希望有人能给出一个有些代码的简单的线程例子就行了。保证100分相送绝对不吝啬!
问题点数:100、回复次数:8Top
1 楼daydreamer77(白日梦)回复于 2001-12-13 08:22:10 得分 0
再问!Top
2 楼liang_z(千山一刀之忍者神龟)回复于 2001-12-13 08:53:26 得分 0
写一个定义与myThread的OnTerminate事件一样的过程:myThreadTerminate,
在myThread[i]:=TmyThread.Create后,用这句:
myThread[i].OnTerminate := myThreadTerminate;
for i:=0 to threadcount do
begin
mythread[i]:=tmythread.create;
myThread[i].OnTerminate := myThreadTerminate;
end;
Top
3 楼liang_z(千山一刀之忍者神龟)回复于 2001-12-13 08:53:55 得分 0
我蒙
我蒙
我蒙蒙蒙!!!Top
4 楼qiandeng(千灯)回复于 2001-12-13 10:00:54 得分 0
用不着事件
在线程的execute
第一行插一句
freeOnTerminate := true;
在最后一行在补上一句
Form1.变量 := Form1.变量 + 1;
Top
5 楼pathe(睡斛)回复于 2001-12-13 10:04:31 得分 50
TMyThread = class(TThread)
private
HandleFrm : integer;
step : integer;
public
constructor Create(handle:integer);
procedure Execute; override;
end;
constructor TMyThread.Create(handle:integer);
begin
HandleFrm := handle;
FreeOnTerminate := True;
inherited Create(false);
end;
procedure TMyThread.Execute;
var
i : integer;
begin
inherited;
for i:= 0 to 10000 do
begin
step := i;
if step = 5000 then
begin
SendMessage(HanldeFrm,WM_SYSCOMMAND,SC_MINIMIZE,0);
//满足条件时发送消息,可以自己定制消息,然后在对应的文件实现消息处理函数
exit;//当然不一定退出;
end;
do sth;
end;
///////////////////////////////////////////////////////////////////////////
关于Form1的定义;
private
{ Private declarations }
ThreadCount : integer;
procedure ThreadDone(Sender: TObject);
.......
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
begin
for i:=0 to ThreadCount - 1 do
begin
with TMythread.Create(Form1.handle) do
OnTerminate := ThreadDone;
end;
procedure TForm1.ThreadDone(Sender :TObject);
begin
Dec(ThreadCount);
if (ThreadCount = 0) then
ShowMessage('All Threads have been done!');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ThreadCount := 20;
end;
希望对你有所帮助!!!!
Top
6 楼copy_paste(木石三)回复于 2001-12-13 10:06:09 得分 50
最好不要分配数组,用TList动态维护。
type
TMyThread = class(TThread)
private
FEvent: THandle;
public
constructor Create(Run: Boolean); override;
destructor Destroy; overrdie;
property Event: THandle read FEvent;
end;
constructor TMyThread.Create(Run: Boolean);
begin
FEvent := CreateSemaphore(nil, 1);
inherited Create(Run);
end;
destructor TMyThread.Destroy;
begin
CloseHandle(FEvent);
end;
procedure TMyThread.Execute;
begin
//初始工作...
//初始完成了,通知Form1我进行线程循环了。Form1主线程可以继续工作了
ReleaseSemaphore(FEvent, 1);
//循环
end;
procedure TForm1.ThreadTerminate(Sender: TObject);
begin
//当每个线程完成Free时,触发这个事件。
Dec(FCount);
end;
procedure TForm1.CreateMyThread;
var
Thread: TMyThread;
begin
Thread := TMyThread.Create(True);
Thread.OnTerminate := ThreadTerminate;
WaitForSingleObject(Thread.Event, 10000); //等Thread进行循环
FThreadList.Add(Thread);
Inc(FCount);
end;
procedure Button1.onclick
begin
for I := 0 to ThreadCount do
CreateThread;
end;
FCount: Integer其时没必要了,可以通过访问FThreadList.Count来知道多少个线程了。
记住Free FThreadList所指的线程资源。
FThreadList: TList//指向TMyThread
procedure FreeThread;
var I: Integer;
begin
for I:= 0 to FThreadList.Count - 1 do
begin
TMyThread(FThreadList[i]).Terminate;
TMyThread(FThreadLIst[I]).Free;
end;
FThreadList.Free;
end;Top
7 楼lizhenjia(暴雪)回复于 2001-12-13 10:58:36 得分 0
学习Top
8 楼daydreamer77(白日梦)回复于 2001-12-13 13:46:23 得分 0
怎样给分的啊???Top




