Jos*_*mar 29 delphi multithreading
我是熟悉Delphi中线程的新手.所以,我试图制作一个简单的查询应用程序,为数据库调用一点并花一点时间,所以我想提醒用户有一个后台进程,必须耐心等待.
我尝试了很多样品,但它们都不适合我,拜托,有人能告诉我一个可以使用的简单样品吗?
我知道我必须声明一种类型的TThread,使用Create和Override Execute ......等等.但是因为我失去了...
使用Delphi 7,SQL Server 2005和ADO,Windows XP sp3.-
谢谢.
him*_*elf 53
是的,你声明一个从TThread继承的新类型:
TMyWorkerThread = class(TThread)
end;
Run Code Online (Sandbox Code Playgroud)
然后为Execute()添加函数覆盖:
TMyWorkerThread = class(TThread)
public
procedure Execute; override;
end;
Run Code Online (Sandbox Code Playgroud)
启动线程时将调用该过程.它将与您的主程序并行执行.我们来写吧.
procedure TMyWorkerThread.Execute;
begin
//Here we do work
DoSomeWork();
DoMoreWork();
//When we exit the procedure, the thread ends.
//So we don't exit until we're done.
end;
Run Code Online (Sandbox Code Playgroud)
怎么用?假设您想在用户单击按钮时开始工作.你编写一个OnClick处理程序:
procedure TMainForm.Button1Click(Sender: TObject);
begin
TMyWorkerThread.Create(false);
end;
Run Code Online (Sandbox Code Playgroud)
而已.用户单击按钮后,您的线程将启动并继续执行您在Execute中编写的任何内容.如果用户再次单击该按钮,则另一个线程将启动,然后是另一个 - 每次单击一个.它们都将并行运行,每个都执行在Execute()中写入的所有内容,然后结束.
假设您要检查工作是否结束.为此,您必须将引用存储在某处:
TMainForm = class(TForm)
{...skipped...}
public
MyWorkerThread: TThread;
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
//This time we make sure only one thread can be started.
//If one thread have been started already, we don't start another.
if MyWorkerThread<>nil then
raise Exception.Create('One thread have already been started!');
MyWorkerThread := TMyWorkerThread.Create(false);
end;
procedure TMainForm.Button2Click(Sender: TObject);
begin
//If the work is not over yet, we display message informing the user we're still working
if (MyWorkerThread<>nil) and (WaitForSingleObject(MyWorkerThread.Handle, 0)<>WAIT_OBJECT_0) then
MessageBox(Self.Handle, pchar("The work is not yet done!"), pchar("Still running"), MB_OK);
end;
Run Code Online (Sandbox Code Playgroud)
如您所见,我们通过调用名为WaitForSingleObject的Windows函数来检查线程是否仍在运行.此函数等待,直到线程完成工作,或超时已过,并且当我们指定超时为0时,如果线程尚未结束,它将立即存在.
Ger*_*lí- 33
您可以在线程网上找到许多示例.如果您在线程内使用ADO连接,唯一的特殊功能是您不能共享相同的连接.
每个线程必须创建自己的连接,否则它们是相同的(应该遵循与任何其他线程相同的规则.)
我用过的样本是这样的:
TADOSQLThread = class(TThread)
private
FADOQ: TADOQuery; // Internal query
FSQL: string; // SQL To execute
FID: integer; // Internal ID
public
constructor Create(CreateSuspended:Boolean; AConnString:String;
ASQL:string; IDThread:integer);
destructor Destroy; override;
procedure Execute(); override;
property ID:integer read FID write FID;
property SQL:string read FSQL write FSQL;
property ADOQ:TADOQuery read FADOQ write FADOQ;
end;
Run Code Online (Sandbox Code Playgroud)
Create构造函数被覆盖,如下所示:
constructor TADOSQLThread.Create(CreateSuspended:Boolean; AConnString:String;
ASQL:string; IDThread:integer);
begin
inherited Create(CreateSuspended);
// ini
Self.FreeOnTerminate := False;
// Create the Query
FADOQ := TAdoquery.Create(nil);
// assign connections
FADOQ.ConnectionString := AConnString;
FADOQ.SQL.Add(ASQL);
Self.FID := IDThread;
Self.FSQL:= ASQL;
end;
Run Code Online (Sandbox Code Playgroud)
而execute方法非常简单:
procedure TADOSQLThread.Execute();
begin
inherited;
try
// Ejecutar la consulta
Self.FADOQ.Open;
except
// Error al ejecutar
...Error treattement
end;
end;
Run Code Online (Sandbox Code Playgroud)
要启动并创建一个线程,您可以使用与此类似的代码:
//crear el Thread
th := TADOSQLThread.Create(True, mmConnection.Lines.Text, ASQL, AId);
// internal for me (for controled the number of active threads and limete it)
inc(numThreads);
// evento finalizacion
th.OnTerminate := TerminateThread;
// Ejecutarlo
th.Resume;
Run Code Online (Sandbox Code Playgroud)
我创建了一个TerminateThread方法,它在完成后接收线程控制.与其他线程唯一不同的是连接问题.您必须在每个线程上创建一个新连接,它不能与其他线程共享相同的ADOConnections.
我希望这个例子对你有用.
问候
| 归档时间: |
|
| 查看次数: |
73836 次 |
| 最近记录: |