DELPHI线程例子-FC
{优秀的数据库应用应当充分考虑数据库访问的速度问题。通常可以通过优化数据库、优化 查询语句、分页查询等途径收到明显的效果。即使是这样,也不可避免地会在查询时闪现一个带有 SQL符号的沙漏,即鼠标变成了查询等待。最可怜的是用户,他(她)在此时只能无奈地等待。遇到急性子的,干脆在此时尝试 Windows中的其它应用程序,结果致使你的数据库应用显示一大片白色的窗口。真是无奈!
本文将以简单的例子告诉你如何实现线程查询。还等什么,赶快打开Delphi对照着下面的完整源代码试试吧。
在查询时能够做别的事情或者取消查询,这只是基本的线程查询,在你阅读了Delphi有关线程帮助之后能立刻实现。这里介绍的是多个线程查询的同步进行。
在Delphi数据库应用中,都有一个缺省的数据库会话 Session。通常情况下,每个数据库应用中只有这一个会话。无论是查询函数修改数据,在同一时间内只能进行其中的一件事情, 而且进行这一件事情的时候应用程序不能响应键盘、鼠标以及其它的 Windows消息。这就是在 窗口区域会显示一片空白的原因所在。当然,只要将查询或数据操纵构造成线程对象,情况会好一些,至少可以接受窗口消息,也可以随时终止查询或数据操纵,而不会在屏幕上显示出太难看的白色。不过,这只是解决了问题的一部分。假如在进行一个线程查询的时候,用户通过 按钮或菜单又发出了另一个查询的命令,这可如何是好,难道终止正在执行的数据库访问吗? 解决之道就是:多线程同步查询。
实现多线程同步查询的基本思想是,为每一个查询组件(如TQuery组件)创建一个独占的 数据库会话,然后各自进行数据库访问。需要特别注意的是,因为Delphi中的 VCL组件大多都 不是线程安全的,所以应当在线程查询结束后再将DataSource组件与查询组件关联,从而显示 在DBGrid组件中。
下面的例子只实现了静态的线程同步查询,即线程对象是固定的,并随窗体的创建和销毁 而创建和销毁。你可以就此进行改进,为每一个数据查询或数据操纵命令创建一个单独的线程对象,从而达到多线程同步查询的目的。
注意:应用程序中的线程不是越多越好,因为线程将严重吞噬CPU资源,尽管看上去并不明显。谨慎创建和销毁线程将避免你的应用程序导致系统资源崩溃。
下面的例子给出了同时进行的两个线程查询。第一次按下按钮时,线程开始执行;以后每次按下按钮时,如果线程处于挂起状态则继续执行,否则挂起线程;线程执行完毕之后将连接 DataSource,查询结果将显示在相应的DBGrid中。
}
{ 这里的多线程同步查询演示程序仅包括一个工程文件和一个单元文件 }
{ 窗体中放置的组件有: }
{ 两个Session组件 }
{ 两个Database组件 }
{ 两个Query组件 }
{ 两个DataSource组件 }
{ 两个DBGrid组件 }
{ 一个Button组件 }
{ 除非特别说明,否则上述各组件的属性都取默认值(见各组件注释) }
{ 对于Database组件,就和一般设置一样,有一个正确的连接即可 }
{ 对于Query 组件,需要在各自的属性 SQL中添加一些查询语句,为了 }
{ 看得更清除,建议不要在两个Query 组件中填写相同的查询语句。 }
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, DBTables, Grids, DBGrids, StdCtrls;
type
TForm1 = class(TForm)
Session1: TSession; { 属性SessionName填写为S1 }
Database1: TDatabase; { 属性SessionName选择为S1 }
Query1: TQuery;{ 属性Database选择为Database1;属性SessionName选择为S1 }
DataSource1: TDataSource; { 属性DataSet设置为空 }
DBGrid1: TDBGrid; { 属性DataSource选择为DataSource1 }
Session2: TSession; { 属性SessionName填写为S2 }
Database2: TDatabase; { 属性SessionName选择为S2 }
Query2: TQuery;{ 属性Database选择为Database2;属性SessionName选择为S2 }
DataSource2: TDataSource; { 属性DataSet设置为空 }
DBGrid2: TDBGrid; { 属性DataSource选择为DataSource2 }
BtnGoPause: TButton; { 用于执行和挂起线程 }
procedure FormCreate(Sender: TObject); { 创建窗体时创建线程对象 }
procedure FormDestroy(Sender: TObject); { 销毁窗体时销毁线程对象 }
procedure BtnGoPauseClick(Sender: TObject); { 执行线程和挂起线程 }
private
public
end;
TThreadQuery = class(TThread) { 声明线程类 }
private
FQuery: TQuery; { 线程中的查询组件 }
FDataSource: TDataSource; { 与查询组件相关的数据感知组件 }
procedure ConnectDataSource;{ 连接数据查询组件和数据感知组件的方法 }
protected
procedure Execute; override;{ 执行线程的方法 }
public
constructor Create(Query: TQuery;
DataSource: TDataSource); virtual; { 线程构造器 }
end;
var
Form1: TForm1;
Q1, { 线程查询对象1 }
Q2: TThreadQuery; { 线程查询对象2 }
implementation
{$R *.DFM}
{ TThreadQuery类的实现 }
{ 连接数据查询组件和数据感知组件}
procedure TThreadQuery.ConnectDataSource;
begin
FDataSource.DataSet := FQuery;{ 该方法在查询结束后才调用 }
end;
procedure TThreadQuery.Execute;{ 执行线程的方法 }
begin
try
FQuery.Open; { 打开查询 }
Synchronize(ConnectDataSource);{ 线程同步 }
except
ShowMessage('Query Error'); { 线程异常 }
end;
end;
{ 线程查询类的构造器 }
constructor TThreadQuery.Create(Query: TQuery; DataSource: TDataSource);
begin
FQuery := Query;
FDataSource := DataSource;
inherited Create(True);
FreeOnTerminate := False;
end;
{ 创建窗体时创建线程查询对象 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Q1 := TThreadQuery.Create(Query1, DataSource1);
Q2 := TThreadQuery.Create(Query2, DataSource2);
end;
{ 销毁窗体时销毁线程查询对象 }
procedure TForm1.FormDestroy(Sender: TObject);
begin
Q1.Terminate; { 销毁之前终止线程执行 }
Q1.Destroy;
Q2.Terminate; { 销毁之前终止线程执行 }
Q2.Destroy;
end;
{ 开始线程、继续执行线程、挂起线程 }
procedure TForm1.BtnGoPauseClick(Sender: TObject);
begin
if Q1.Suspended then Q1.Resume else Q1.Suspend;
if Q2.Suspended then Q2.Resume else Q2.Suspend;
end;
end.
DELPHI线程例子-FC的更多相关文章
- delphi 线程教学第六节:TList与泛型
第六节: TList 与泛型 TList 是一个重要的容器,用途广泛,配合泛型,更是如虎添翼. 我们先来改进一下带泛型的 TList 基类,以便以后使用. 本例源码下载(delphi XE8版本) ...
- 多线程的基本概念和Delphi线程对象Tthread介绍
多线程的基本概念和Delphi线程对象Tthread介绍 作者:xiaoru WIN 98/NT/2000/XP是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用CPU运行 ...
- TMsgThread, TCommThread -- 在delphi线程中实现消息循环
http://delphi.cjcsoft.net//viewthread.php?tid=635 在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使 ...
- TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)
在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供. 花了两天的事件研究了 ...
- Delphi线程定时器TThreadedTimer及用法--还有TThreadList用法可以locklist
Delphi线程定时器 - -人生如歌- - 博客园http://www.cnblogs.com/zhengwei0113/p/4192010.html (* 自己编写的线程计时器,没有采用消息机制, ...
- delphi 线程教学第二节:在线程时空中操作界面(UI)
第二节:在线程时空中操作界面(UI) 1.为什么要用 TThread ? TThread 基于操作系统的线程函数封装,隐藏了诸多繁琐的细节. 适合于大部分情况多线程任务的实现.这个理由足够了吧 ...
- delphi 线程教学第一节:初识多线程
第一节:初识多线程 1.为什么要学习多线程编程? 多线程(多个线程同时运行)编程,亦可称之为异步编程. 有了多线程,主界面才不会因为耗时代码而造成“假死“状态. 有了多线程,才能使多个任务同时 ...
- 微软手写识别模块sdk及delphi接口例子
http://download.csdn.net/download/coolstar1204/2008061 微软手写识别模块sdk及delphi接口例子
- delphi 线程教学第一节:初识多线程(讲的比较浅显),还有三个例子
http://www.cnblogs.com/lackey/p/6297115.html 几个例子: http://www.cnblogs.com/lackey/p/5371544.html
随机推荐
- 【SQLServer2008】之如何导入mdf,ldf文件、导入.mdf文件报错解决问题以及如何获得Authenticated Users 权限
一.如何导入mdf,ldf文件: 链接:http://jingyan.baidu.com/article/09ea3ede21258cc0afde3943.html 二.导入.mdf文件报错解决问题 ...
- 推荐一个android 日期时间选择器(转)
最近接触了日期选择的功能,那么肯定得需要一个日期选择控件,Android 系统有自带的 DatePicker 控件,但是不说这个控件有多 难看吧,现在 Android 手机版本那么多,用户弹出来的控件 ...
- Effective C++ 49,50
49.熟悉标准库. C++标准库非常大. 首先标准库中函数非常多,为了避免名字冲突.使用命名空间std.而之前的库函数都存放于< .h>中,如今成为伪标准库.而不能直接将这些头文件所有直接 ...
- 首页底部菜单FragmentTabHost的使用
一般现在的菜单都是底部FragmentTabHost,切换Fragment来实现的,今天我们就使用这个来看看如何实现的 首先是布局文件 <?xml version="1.0" ...
- 【BZOJ3784】树上的路径 点分治序+ST表
[BZOJ3784]树上的路径 Description 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a< ...
- [Android]彻底去除Google AdMob广告
应用中包含广告是能够理解的,但经常造成用户误点,或者广告切换时造成下载流量,就有点让人不舒服了. 以下就以Google AdMob广告为例,看怎样彻底去除他. 先分析一下Google AdMob的工作 ...
- 【python】-- pymsql 操作MySQL
pymysql 对MySQL数据库进行简单数据操作python模块主要是:MySQLdb.pymsql,MySQLdb模块主要用于python2.X,而python3.X则使用pymsql,pymys ...
- Android笔记之自定义的RadioGroup、RadioButton,以及View实例状态的保存与恢复
效果图 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLay ...
- 让lu哥头痛了许久的代码(洛谷:树的统计)
错在单点修改时传的是a,应该是id[a](Line 89).谨记!!! //fushao zuishuai #include <cstdio> #include <cstring&g ...
- emmet缩写格式
2016年5月30日 10:10 标准网页<!DOCTYPE html> <html lang="zh-CN"> <head> <meta ...