我们知道, WIN95或WIN NT都是"多线程"的操作系统,在Delphi2.0中,我们可 以充分利用这一特性,编写出"多线程"的应用程序。 对以往在DOS或16位windows下写程序的人来说,"多线程"仍然是陌生的,但如 同以前我们从DOS下的单任务过渡到windows 3.1下的多任务,如今我们又必须过渡 到"多线程"领域,毕竟
计算机时代是在不断发展的。不过,幸运的是,在Delphi2.0下进 行多线程程序设计并不需要我们去
学习庞大的WIN32API函数,我们可以利用Delphi 下标准的多线程类TThread来完成我们的
工作。 TThread是一个abstract(抽象)类,也就是说,并不需要根据TThread来声明变量(而 且根据TThread声明的变量也是完全无用),我们要做的是把TThread作为基类,用继 承的形式来生成子类。实际上,根据TThread来写多线程应用程序是非常容易的。 下面就是一个基本的继承TThread生成的多线程类。
QuerThrd.Pas
Unit QuerThrd; Interface
Uses Classes,DBTables;
Type TQueryThread=class(TThread) private fQuery:TQuery; protected procedure Execute;override; public constructor Create(Suspended:Boolean; Query:TQuery); end;
implementation
constructor TQueryThread.Create(Suspended:Boolean;Query:TQuery); begin inheritedCreate(Suspended); fQuery:=Query; FreeOnTerminate:=True; end;
procedure TQueryThread.Execute; begin fQuery.Open; end;
end.
在上面这个简单的例子中,我们构造了一个TThread的子类TQueryThread,用于 在后台执行数据库查询。 在该类的Create函数中,传递了两个参数Suspended和Query, 其中Suspended用于控制线程的运行,如果Suspend为真,TQueryThread类的线程在建 立后将立即被悬挂,一直到运行了Resume方法,该线程才会继续执行,Query参数用于 接受一个已经存在的Query控件(在窗体中真正的Query控件)而使它在多线程的情 况下运行。 Execute是最重要的过程,它是类TQueryThread的执行部分,所有需要在这 个多线程类中运行的语句都必须写在这个过程里。 实际上构造自己的多线程类时,并不需要输入所有的这些代码,选择
Delphi的 File菜单下的new选项,再选"TThreadObject"项目,Delphi就会为你构造基本的程序模 块。然后我们可以根据需要再做相应的修改。 进程的执行: 假设我们已经建立了一个窗体Form1,窗体中有我们将要使用的查询控件 Query1。那么我们在该单元的USES部分加入上面写的QuerThrd单元。
procedure TForm1.Button1Click(Sender:TObject); begin {建立一个运行的进程} TQueryThread.Create(False,Query1); end;
如果这个过程被执行,那么窗体中的
查询控件Query1就会自动在多线程的环境 下运行查询。注意TQueryThread类中只有Create而没有Free,动态建立类以后又忘 记删除是我们常犯的错误之一,不过在这里由于我们指定了FreeOnTerminate(运行完 即删除)为真,所以当Execute里的语句执行完后,TQueryThread类占据的内存空间将 被自动释放。 然而还有一个问题值得我们注意,由于同一时刻可以有多个线程同时运行,那么 我们还必须解决好同步的问题,如果几个多线程程序之间没有任何关联,那么它们之 间也不会有任何冲突。 但实际上,可能同时运行几个多线程的数据库应用程序,由于需 要共享相同的数据库资源,我们还需要为Query1增加一个Tsession控件。 其实,虽然我们也许没有亲自使用过Session控件,但实际上,在所有的数据库访问 时Delphi都会自动建立一个临时的Session控件,使用完后又动态地删除掉它。在平 常的数据库编程时,用不着我们亲自来操作,但在数据库多线程执行的情况下,为了不 相互冲突,我们必须为每个数据库访问都定制自己的Session控件。这个步骤非常简 单,我们只需要在窗体中增加一个Session控件