现在我用一个ADOConnection 连接到MSSQL,在FORM上放有多个Table、DataSource、DBGrid.并一对一地关联好,现在我想要实现在多线程的方法同时打开这几个Table.代码如下:QueryThread= class(TThread)
private
FSP:TAdoStoredproc;
PName:string;
FSPException:Exception;
procedure FSPError;
protected
procedure Execute; override;
public
Constructor Create(FP:TAdoStoredproc;FName:String);virtual;
//Destructor Destroy;override;
end;
implementation{$R *.dfm}
var
Nextnumber:integer=0;
Doneflags:integer=0;
Hsem:Thandle=0;
Constructor QueryThread.Create(FP:TADOStoredproc;FName:String);
begin
inherited create(False);
FreeOnTerminate:=True;
FSP:=FP;
Pname:=Fname;
resume;
end;procedure QueryThread.Execute;
var
I:integer;
WaitReturn:DWORD;
begin
Onterminate:=form1.ThreadsDone;
WaitReturn:=Waitforsingleobject(Hsem,Infinite);
if WaitReturn=WAIT_OBJECT_0 then
begin
with FSP do
begin
Close;
TableName:=Trim(PName);
try
Prepared:=true;
open;
except
FSPException:=Exceptobject as exception;
synchronize(FSPError);
end;
end;
end;
ReleaseSemaphore(hSem,1,nil);
end;
procedure QueryThread.FSPError;
begin
application.ShowException(FSPException);
end;procedure TForm1.ThreadsDone(Sender:Tobject); //一点同步的代码,但没有的
var
i:integer;
begin
inc (Doneflags);
if doneflags=2 then
closehandle(hsem);
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Hsem:=createSemaphore(nil,1,1,nil);
Querythread.Create(T1,'Test');
Querythread.Create(T2,'Test');
QueryThread.Create(T3,'test');
end;
为什么会有错误的呢,请各位多多介绍下在数据库多线程应用。
private
FSP:TAdoStoredproc;
PName:string;
FSPException:Exception;
procedure FSPError;
protected
procedure Execute; override;
public
Constructor Create(FP:TAdoStoredproc;FName:String);virtual;
//Destructor Destroy;override;
end;
implementation{$R *.dfm}
var
Nextnumber:integer=0;
Doneflags:integer=0;
Hsem:Thandle=0;
Constructor QueryThread.Create(FP:TADOStoredproc;FName:String);
begin
inherited create(False);
FreeOnTerminate:=True;
FSP:=FP;
Pname:=Fname;
resume;
end;procedure QueryThread.Execute;
var
I:integer;
WaitReturn:DWORD;
begin
Onterminate:=form1.ThreadsDone;
WaitReturn:=Waitforsingleobject(Hsem,Infinite);
if WaitReturn=WAIT_OBJECT_0 then
begin
with FSP do
begin
Close;
TableName:=Trim(PName);
try
Prepared:=true;
open;
except
FSPException:=Exceptobject as exception;
synchronize(FSPError);
end;
end;
end;
ReleaseSemaphore(hSem,1,nil);
end;
procedure QueryThread.FSPError;
begin
application.ShowException(FSPException);
end;procedure TForm1.ThreadsDone(Sender:Tobject); //一点同步的代码,但没有的
var
i:integer;
begin
inc (Doneflags);
if doneflags=2 then
closehandle(hsem);
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Hsem:=createSemaphore(nil,1,1,nil);
Querythread.Create(T1,'Test');
Querythread.Create(T2,'Test');
QueryThread.Create(T3,'test');
end;
为什么会有错误的呢,请各位多多介绍下在数据库多线程应用。
解决方案 »
- socket编程的小小问题
- 关于创建一个过程的问题
- 鲨鱼请教:今天面试的问题?
- 出现提示“缺少更新或刷新的基本表消息”很奇怪呢!?
- sql语句在程序中实现的结果和在查询分析器中的结果不一样,高手指教
- 请教高手 快行动 当场给分--------在线等待
- 请问那里可以下载Delphi的基础书籍,eshu形式的最好了,谢谢
- 图像中找直线,我用的hough变化速度太慢了,大家来看看见啊! 在线等
- ip3000的DBNavigator控件的删除按钮的提示怎么老是不能汉化
- 请问如何设置LMD IEBUTTON的属性。让它的文字在图像的下面?它默认的是在右边
- *****怎么实现数据的保存******
- 简单问题请教!!!!有关SQL的数据类型!
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses Unit2;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
T1, T2, T3: TADOStoredProc;
begin
T1:= TADOStoredProc.Create(self);
T2:= TADOStoredProc.Create(self);
T3:= TADOStoredProc.Create(self);
TQuerythread.Create(T1,'Test');
TQuerythread.Create(T2,'Test');
TQueryThread.Create(T3,'Test');
end;end.--------------------------------------------------
unit Unit2;interfaceuses
Classes, ADODB;type
TQueryThread = class(TThread)
private
FSP:TAdoStoredproc;
PName:string;
procedure doit;
protected
procedure Execute; override;
public
Constructor Create(FP:TAdoStoredproc;FName:String);virtual;
end;implementationConstructor TQueryThread.Create(FP:TADOStoredproc;FName:String);
begin
inherited create(False);
FreeOnTerminate:=True;
FSP:=FP;
Pname:=Fname;
resume;
end;procedure TQueryThread.Execute;
begin
synchronize(doit);
end;procedure TQueryThread.doit;
begin
with FSP do
begin
ConnectionString:= 'Provider=MSDASQL.1;Persist Security Info=False;User ID=test01;Data Source=MS Access Database;Initial Catalog=C:\我的文档\test01';
ProcedureName:=PName;
Prepared:=true;
open;
end;
end;end.
给出以下改进建议:1. 最好在声明线程类时, 将其名字前加上T, 比如本例的TQueryThread, 否则写起来很不方便.
2. 线程中凡是涉及到窗体的部分都要同步, 比如TQueryThread.doit部分进行的操作就要在TQueryThread.Execute中用synchronize(doit)调用.
3. Unit1中使用T1, T2, T3时, 要先声明并实例化, 否则会出现错误.
4. 再有一点我不太明白, 你要打开Tabel为什么要用TADOStoredproc? TADOStoredproc根本没有TableName属性呀? 可以考虑使用TADOCommand, 通过设置其CommandType和CommandText可以对Table, Query, StoredProc等各种类型进行操作.不知我是否解决了你的问题, 如还有疑问请将具体的错误提示信息写出来, 以便大家分析.
但问题是Delphi又是如何知道它们都代表test而不是多个互不相干的数据库呢? 这就需要TSession帮忙. 通过设置TDatabass和TDataSet的SessionName属性, 以及唯一产生SessionName(就像DatabaseName一样)就可以实现数据库的多线程处理.
请看这样一段代码:UniqueNumber := GetUniqueNumber;Session.SessionName := Format('%s%x', [Session.Name, UniqueNumber]);
Database.DatabaseName := Format('%s%x', [Database.Name, UniqueNumber]);
Database.SessionName := Session.SessionName;Query.SessionName := Session.SessionName;
Query.DatabaseName := Database.DatabaseName;
Query.Open;
所以除非你使用多线程访问不同的数据库, 否则就要在线程中对Session和Database进行唯一化.