为何ado创建和连接放在线程中就会出错,有谁知道啊(200分)

  • 主题发起人 主题发起人 yubing8
  • 开始时间 开始时间
Y

yubing8

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ComCtrls, DB, ADODB,inifiles,StrUtils;
type
Tdbfthread=class(tthread)
private
protected
procedure execute;override;
public
end;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Tdbfthread.Create(false);
end;

{ Tdbfthread }
procedure Tdbfthread.execute;
var
myado:tadoquery;
begin
myado:=tadoquery.Create(nil);
myado.ConnectionString:='Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=teach;'+
'Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=AOP-YB;Use Encryption for Data=False;Tag with column collation when possible=False';
myado.SQL.Clear;
myado.SQL.Text:='CREATE TABLE bbb (ID char(8),PASSWD char(15),AUTHORITY char(1))';
myado.ExecSQL;
myado.Free;
end;
end.
 
Adoquery不要动态创建,换成一个adoquery在form上试试
 
在form上我当然会了,我的目的就是要在线程中创建adoquery
 
不是说您会不会,是线程中不有create()这样的函数出现,还有线程还不能使用showmessage('aa'),messagebox(..)等,会出错的
 
不会吧,那线程的限制也太多了吧
 
不在线程中使用就完全正确,很郁闷
 
谁有更好的办法啊,我很急
 
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ComCtrls, DB, ADODB,inifiles,StrUtils, Grids,
DBGrids;
type
Tdbfthread=class(tthread)
private
protected
procedure execute;override;
public
end;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//ADOQuery1.Active:=true;
Tdbfthread.Create(false);
end;

{ Tdbfthread }
procedure Tdbfthread.execute;
var
source:tfilestream;
//文件流
reccount,recall,recstart,y,m,d,i,j,step,length,rstart:integer;
dst,filename,date,temp,tablename,sqlstr:string;
lcolumn:Tlistcolumn;
lv:tlistitem;
myado,myupdate:tadoquery;
mychar:char;
begin

myado:=tadoquery.Create(nil);
myado.ConnectionString:='Provider=SQLOLEDB.1;Password=123456;Persist Security Info=True;User ID=sa;Initial Catalog=teach;'+
'Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=AOP-YB;Use Encryption for Data=False;Tag with column collation when possible=False';
myado.SQL.Clear;
myado.SQL.Text:='CREATE TABLE bbb (ID char(8),PASSWD char(15),AUTHORITY char(1))';
myado.ExecSQL;
myado.Free;
end;
end.

这样为何又对了,谁能解释一下
 
为什么线程的问题回答的人这么少呢
 
你是不是在启动线程之前在主Form中做过Ado的操作(例如 查询)
 
多线程的程序是十分难调试的,因为有很多错误并不是什么时候都会出现,这本身就是写多线程程序的一个难点。
你说一下你的出错信息吧!
 
在线程中调用ADO时,一般要初始化COM,调用CoInitialize
因为对Com的初使化好像只对当前线程有效
CoInitialize(nil);
try
//使用ADO
finally
CoUninitialize;
end;
 
lubfc:是的,不过问题已基本解决,我是用线程同步,把form中需要执行的程序放在同步执行,不过线程写的很麻烦,让我感到很不爽,还想和大家继续讨论,请大家发表一下对线程的高见
 
我觉得,对于一般并发数少的操作,用Thread的Synchronize一般说来是可以了,
而对于并发数多的操作,如服务程序,的话,用消息机制PostMessage来实现和
From(特别是用户界面)的通信比较好.我试验过,效果是很明显的
 
解決方法有兩個:
1.如estorm所說,在線程中使用CoInitialize與CoUninitialize.
2.不要在線程中創建ADO控件,在線程創建時將主程程的ADO控件傳入,下面是一個例子如:
type
TQueryThread=class(TThread)
private
FHandle:HWND;
FHasResult:Boolean;
FQuery:TAdoQuery;
procedure QueryExecute;
procedure QueryOpen;
protected
procedure Execute;override;
public
constructor Create(AHandle:HWND;
AdoQuery:TAdoQuery;
HasResult:Boolean);
end;

implementation
constructor TQueryThread.Create(AHandle:HWND;AdoQuery: TAdoQuery;
HasResult: Boolean);
begin
inherited Create(True);
FreeOnTerminate:=True;
FHandle:=AHandle;
FQuery:=AdoQuery;
FHasResult:=HasResult;
Resume;
end;

procedure TQueryThread.Execute;
begin
if FHasResult then
QueryOpen
else
QueryExecute;
end;

procedure TQueryThread.QueryExecute;
begin
try
FQuery.ExecSQL;
PostMessage(FHandle, WM_ThreadDone, Self.ThreadID,0);
except
on E:Exceptiondo
PostMessage(FHandle,WM_ThreadDone, Self.ThreadID,MaxInt);
end;
end;

procedure TQueryThread.QueryOpen;
begin
try
FQuery.Open;
PostMessage(FHandle, WM_ThreadDone, Self.ThreadID,0);
except
on E:Exceptiondo
PostMessage(FHandle,WM_ThreadDone, Self.ThreadID,MaxInt);
end;
end;
 
多人接受答案了。
 
后退
顶部