Thread线程启用问题,很简单,在线等,马上结贴。速来拿分!

eFainter 2016-05-05 08:40:33
想法是这样的,创建线程后,根据需要执行,现场执行完后,不注销,下次还要继续启用执行。
现在的问题是第一次执行后,第二次我不知道怎么调用,我创建的时候是create(true),第一次resume正常执行线程,onterminate事件也正常执行,但是第二次我不清楚用什么方式执行了,还是线程只能一次性的,第二次又需要从新创建?
还有一个问题OnTerminate执行完毕后,线程是处于什么状态,我TForm1.Button2Click(Sender: TObject);时间中调用线程Terminated是False,按直观理解,应该是True啊。请大侠帮忙解答下。

{ TMyThread }

constructor TMyThread.Create(ASuspended: Boolean);
begin
inherited Create(ASuspended);
end;

procedure TMyThread.Execute;
begin
inherited;

ShowMessage('3');
end;

{ TForm1 }

procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(FMyThread) then FMyThread.Destroy;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(FMyThread) then
begin
FMyThread := TMyThread.Create(True);
FMyThread.OnTerminate := ThreadTerminate;

FMyThread.Resume
end
else FMyThread.Resume
end;

procedure TForm1.ThreadTerminate(Sender: TObject);
begin
ShowMessage('jieshule');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if FMyThread.Terminated then ShowMessage('Terminated')
else ShowMessage('not Terminated');
end;
...全文
728 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
findcsdn 2016-07-11
  • 打赏
  • 举报
回复
1. 看情况的,如果线程的起停不是很频繁,那就用的时候创建,不用的时候销毁。 下面是我写的com口通讯的起停。 procedure TAlmDev.Start; begin try FComPort.Open; FStop := False; except on e: exception do MsgBox(Format('%s: %s', [FComPort.Port, e.message])); end; // if FComPort.Connected and (FComThread = nil) then begin FComThread := TCommThread.Create(Self); end; end; procedure TAlmDev.Stop; begin FStop := True; FComPort.Stop; // if FComThread <> nil then begin FComThread.Free; FComThread := nil; end; // FComPort.Close; end; 2。如果是起停非常频繁,类似于用在线程缓冲池的时候,就可以用事件,使线程在不用的时候处于阻塞状态,用到时候发送信号给事件,线程就开始循环了。 3。还有一种用法比较特殊,就是在外部线程中,调用 suspend 和 resume来起停线程,不过这种方法不常用,主要是起停的时候线程运行状态不太好确定。 针对楼主说的已经触发 ontermitate事件,说明线程已经销毁了,不可能在resume了。
jayqiang 2016-06-02
  • 打赏
  • 举报
回复
使用信号量控制!
  • 打赏
  • 举报
回复
procedure TMyThread.Execute; begin while not terminated do begin DoSomeThing; FEvent.WaitFor(INFINITE); end; end; 如果要线程再跑一次, 把FEvent带上信号,FEvent.SetEvent;
haibianzhibei 2016-06-02
  • 打赏
  • 举报
回复
同意楼上。 或者增加一个定时器,不断调用
lyhoo163 2016-05-06
  • 打赏
  • 举报
回复
线程就是执行完,自动结束。否则占用CPU,会造成系统阻塞。
pathletboy 2016-05-06
  • 打赏
  • 举报
回复
你描述的问题其实是有现成的,“线程池”,线程需要不停的从List中取出任务进行执行,没有任务的时候就阻塞在取任务,当然多线程要考虑资源竞争的问题,你可以搜索下 “Delphi 线程池实现”
wzzwwz 2016-05-06
  • 打赏
  • 举报
回复
引用 6 楼 eFainter 的回复:
兄弟们,你们没有按我的问题回答啊,你们说的说的内容我知道
实际上Delphi对TThread的设计就是把Execute过程用Windows的多线程机制运行了一下。所以当Execute过程执行完了,多线程也就结束了。 所以说,你想让线程一直活着随时让你使用,就不能让Execute结束。那么你在Execute里就需要写一个循环(while/repeat),空闲时Sleep一下防止占用cpu太多,有任务时,设置一下某个变量,Execute里的循环检查到这个变量后继续执行任务(这个任务可以是其他你写好的函数或者过程)。
  • 打赏
  • 举报
回复
procedure TMyThread.Execute; begin repeat // do something Suspend; until Terminated; end;
eFainter 2016-05-05
  • 打赏
  • 举报
回复
兄弟们,你们没有按我的问题回答啊,你们说的说的内容我知道
  • 打赏
  • 举报
回复
在windows上是没有问题的,因为Suspend实际上是API SuspendThread的包装,但是在android上可能没有实现。标注deprecated并非废弃、不能使用,而是代表不赞同使用、过时的意思(因为跨平台的缘故)。
lyhoo163 2016-05-05
  • 打赏
  • 举报
回复
比较典型的用法。充分利用Delphi封闭的Tthread 一、声明一个自己的引用Tthread的类 type TGaugeThread = class(Tthread) protected procedure Execute;override; end; 二、声明一个线程全局变量。一个boolean变量,用于自己控件关闭线程 var MyThread:TGaugeThread; ThreadOn:Boolean; 三、写一个实现部分 procedure TGaugeThread.Execute; var i: integer; begin ThreadOn:=True; ThreadEnd:=False; FreeOnTerminate:=true; i:=0; repeat i:=i+1; if i>=99 then i:=1; GaugeFrm.Gauge1.Progress:=i; application.ProcessMessages; sleep(75); until Terminated or ThreadEnd; GaugeFrm.close; ThreadOn:=False; end; 四、调用线程(可以多次调用) MyThread:=TGaugeThread.Create(False); 五、关闭线程 ThreadEnd:=False
看那山瞧那水 2016-05-05
  • 打赏
  • 举报
回复
改动的: http://blog.csdn.net/jankercsdn/article/details/51323690
看那山瞧那水 2016-05-05
  • 打赏
  • 举报
回复
我是用事件+WaitForObject方式实现的,2010还是2007以后,suspend方法已经废弃了,可以参考下我的实现 http://blog.csdn.net/jankercsdn/article/details/8874469 关于线程退出处理,还是有不完善的地方,实际使用中有改动,以后整理了再发。
从零开始讲述Java多线程的核心知识,通过板书和一步一步画图的方式,引领大家逐步去理解和掌握这些知识;并深入分析源码实现,理解背后的实现原理,知其然还要知其所以然。从多线程核心基础讲起,理解线程的风险,多种创建线程的方式;再到深入理解线程的状态;然后是线程的基本操作。系统、深入、快速上手实现多线程。 课程目标:    快速上手掌握Java多线程的经典课程,    系统、全面、深入掌握Java多线程的核心知识主讲老师:CC老师     20年Java开发和使用经验,多年的首席架构师和CTO,畅销原创书籍《研磨设计模式》的作者。         参与和领导了上百个大中型项目的设计和开发,在互联网应用系统架构、系统设计、    应用级框架和中间件开发等方面具有很多经验和领悟。    更为难得的是,入行20年,仍然奋战在技术一线,深知一线架构师需要掌握哪些技术、    掌握到什么程度、一线架构设计会遇到哪些坑、如何才能做出最合适的架构设计,经验最难得!适应人群:    想要系统、深入学习Java多线程    已有Java开发基础,想要快速掌握Java多线程    补充Java多线程知识,为进入一线大厂做准备学习方式:随到随学课程内容:第一节课:系统理解Java并发编程的知识体系    1:为什么要掌握Java并发编程    2:整个课程的目标    3:整个课程的学习内容第二节课:线程必备基础知识    1:理解线程是什么,理解进程,图示    2:理解轻量级的含义    3:理解时序调度,线程是时序调度的基本单元,图示    4:理解调度方式:抢占式,图示    5:理解我们写的程序基本都是多线程的应用,图示    6:理解并发和并行,图示    7:为什么需要线程第三节课:线程的风险    1:线程安全性问题,图示    2:线程的活跃度问题:死锁、饥饿、活锁,图示    3:线程的性能问题,这里主要是线程间切换 上下文的开销第四节课:创建线程的方式之一    1: 代码演示:实现Runnable接口的方式来创建线程    2:学习Thread类的方法和属性的应用    3:学习Thread类的源码第五节课:创建线程的方式之二    1:继承Thread的方式来创建线程    2:继续学习Thread类的源码,分析线程初始化过程    3: 代码演示:演示ThreadGroup    4: 代码演示:演示daemon线程,理解daemon线程和主线程的关系第六节课:创建线程的方式之三    1: 代码演示:匿名内部类的方式来创建线程    2:继续学习Thread类的源码,分析run方法的调用过程    3:代码演示:callable的方式来创建线程,带返回值    4: 学习FutureTask的部分源码,分析run方法到call方法的调用过程第七节课:线程状态详解    1:通过Thread源码来查看线程状态的定义    2:一步一步画图,讲述状态之间的变迁第八节课:线程的基本操作sleep 和yield    1:阅读Thread源码    2:代码演示:sleep的使用    3:代码演示:yield的使用    4:sleep和yield的对比理解第九节课:线程的基本操作join和interrupt    1:阅读Thread源码    2:代码演示:join的使用    3:代码演示:interrupt的使用这里是《Java并发编程与源码分析》的第一部分——讲述多线程核心基础实现快速上手多线程的经典之作   

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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