写此技术共享贴的目的:
1.这两天工作要用到线程,故学习相关知识
2.前一段时间回答过几个有关于线程的问题
最主要目的是为大家更快地解决问题!现想总结一下线程常用的知识,如有不对之处,请高手(如僵哥等)补充并给个批注!1.如不用时间控件,实现用线程以做周期循环处理
2.访问界面控件时注意事项
VCL(TCanvas除外)都是假设为单线程进行处理的,所以在线程中处理与UI交互时,要委托主线程帮它们处理
3.正常地退出线程(非正常退出线程时,线程内的资源不能正常的释放,有时会出一些错误)
4.在单线程环境下,大家都用TList来存储对象,在多线程的环境下,可以直接用ThreadList来存储对象,因为它已经有了临界区功能
5.线程互斥(改天写例子)
:)下面是我写的一个极简单的线程代码,用来实现累加,且每隔一定的周期进行累加一次,累加之后将值传入控件中,在停止计算时通知线程结束!//线程类
unit Unit2;interfaceuses
Classes,sysutils,SyncObjs,Dialogs;
type
TTest = class(TThread)
private
{ Private declarations }
FSum:Integer;
procedure UpdateCaption;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
end;
implementation
uses Unit1;procedure TTest.UpdateCaption;
begin
Form1.Edit1.Text := Inttostr(FSum);
showmessage('Sum Process End');
end;procedure TTest.Execute;
begin
//必须循环来判断Terminated标志
while not Terminated do
begin
FSum:=FSum+1;//这里可以执行其它独立的任务,例如生成带有独立任务的线程
case QuitEvent.WaitFor(60*100) of //阻塞时间,即Timer.Interval
wrSignaled, wrAbandoned: Terminate;
end;
Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
end;
{ Place thread code here }
end;constructor TTest.Create(CreateSuspended: Boolean);
begin
inherited;
FSum:=0;
end;end.
//主线程代码
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,SyncObjs;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure NotifySumThreadsToQuit;var
Form1: TForm1;
QuitEvent: TEvent;//事件说白了就是一个全局的布尔变量,用SetEvent置为一种状态,便于在线程循环时根据该标识来将线程中止
implementationuses Unit2;{$R *.dfm}procedure NotifySumThreadsToQuit;
begin
QuitEvent.SetEvent;//置信号
end;procedure TForm1.Button1Click(Sender: TObject);
var
Thd:TTest;
begin
Thd:=TTest.Create(True);
Thd.FreeOnTerminate:=False;
Thd.Resume;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
NotifySumThreadsToQuit//通知线程结束
end;initialization
QuitEvent := TEvent.Create(nil,true,false,'SumProcessEnd');//创建事件finalization
QuitEvent.Free;//释放事件
end.
1.这两天工作要用到线程,故学习相关知识
2.前一段时间回答过几个有关于线程的问题
最主要目的是为大家更快地解决问题!现想总结一下线程常用的知识,如有不对之处,请高手(如僵哥等)补充并给个批注!1.如不用时间控件,实现用线程以做周期循环处理
2.访问界面控件时注意事项
VCL(TCanvas除外)都是假设为单线程进行处理的,所以在线程中处理与UI交互时,要委托主线程帮它们处理
3.正常地退出线程(非正常退出线程时,线程内的资源不能正常的释放,有时会出一些错误)
4.在单线程环境下,大家都用TList来存储对象,在多线程的环境下,可以直接用ThreadList来存储对象,因为它已经有了临界区功能
5.线程互斥(改天写例子)
:)下面是我写的一个极简单的线程代码,用来实现累加,且每隔一定的周期进行累加一次,累加之后将值传入控件中,在停止计算时通知线程结束!//线程类
unit Unit2;interfaceuses
Classes,sysutils,SyncObjs,Dialogs;
type
TTest = class(TThread)
private
{ Private declarations }
FSum:Integer;
procedure UpdateCaption;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
end;
implementation
uses Unit1;procedure TTest.UpdateCaption;
begin
Form1.Edit1.Text := Inttostr(FSum);
showmessage('Sum Process End');
end;procedure TTest.Execute;
begin
//必须循环来判断Terminated标志
while not Terminated do
begin
FSum:=FSum+1;//这里可以执行其它独立的任务,例如生成带有独立任务的线程
case QuitEvent.WaitFor(60*100) of //阻塞时间,即Timer.Interval
wrSignaled, wrAbandoned: Terminate;
end;
Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
end;
{ Place thread code here }
end;constructor TTest.Create(CreateSuspended: Boolean);
begin
inherited;
FSum:=0;
end;end.
//主线程代码
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,SyncObjs;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure NotifySumThreadsToQuit;var
Form1: TForm1;
QuitEvent: TEvent;//事件说白了就是一个全局的布尔变量,用SetEvent置为一种状态,便于在线程循环时根据该标识来将线程中止
implementationuses Unit2;{$R *.dfm}procedure NotifySumThreadsToQuit;
begin
QuitEvent.SetEvent;//置信号
end;procedure TForm1.Button1Click(Sender: TObject);
var
Thd:TTest;
begin
Thd:=TTest.Create(True);
Thd.FreeOnTerminate:=False;
Thd.Resume;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
NotifySumThreadsToQuit//通知线程结束
end;initialization
QuitEvent := TEvent.Create(nil,true,false,'SumProcessEnd');//创建事件finalization
QuitEvent.Free;//释放事件
end.
解决方案 »
- Treeview的事件
- 给Context.connection.IOHandler.OnWork:= ××.DoWork怎么会出现不匹配编译错误》
- 关于ASTA的使用问题
- 【新手】工具栏的竖线怎么实现?
- 如何把dbgrid中的数字显示为字符串
- 急救!ADOquery+dbgredeh 怎样将BOOL值在DBGRID中显出来是文字,在线结分!
- 简单问题取得窗口的大小
- 现金报酬找delphi开发高手帮我做一个关于WebBrowser 的程序。
- 推荐一下,那种手机好?
- 怎么从文本文件里取出其内容?
- 三层Corba Server Application与Corba Object
- 请问在delphi中如何实现一个隐藏窗口?
procedure TTest.Execute;
begin
//必须循环来判断Terminated标志
while not Terminated do
begin
FSum:=FSum+1;//这里可以执行其它独立的任务,
//例如生成带有独立任务的线程,若不考虑用线程池,仅需要将新生成的线程的FreeOnTerminated:=True,就可以使它自生自灭了:)
case QuitEvent.WaitFor(60*100) of //阻塞时间,即Timer.Interval
wrSignaled, wrAbandoned: Terminate;
end;
Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
end;
{ Place thread code here }
end;
没人顶~
睡觉!
和
WaitForSingleObject(QuitEvent, 60*100)
的区别,是不是上面有的返回值,而下面的没有?我一般喜欢用下面的形式。
无语
WaitFor就是用WaitForSingleObject实现的function TEvent.WaitFor(Timeout: LongWord): TWaitResult;
begin
case WaitForSingleObject(Handle, Timeout) of
WAIT_ABANDONED: Result := wrAbandoned;
WAIT_OBJECT_0: Result := wrSignaled;
WAIT_TIMEOUT: Result := wrTimeout;
WAIT_FAILED:
begin
Result := wrError;
FLastError := GetLastError;
end;
else
Result := wrError;
end;
可以具体讲讲吗?RPC同步
begin
//必须循环来判断Terminated标志
while not Terminated do
begin
FSum:=FSum+1;//这里可以执行其它独立的任务,
//例如生成带有独立任务的线程,若不考虑用线程池,仅需要将新生成的线程的FreeOnTerminated:=True,就可以使它自生自灭了:)
case QuitEvent.WaitFor(60*100) of //阻塞时间,即Timer.Interval
wrSignaled, wrAbandoned: Terminate;
end;
Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
end;
{ Place thread code here }
end;
然后提供一个public方法让外部对其SetEvent。
这样这个线程类复用起来也比较方便