多线程查询数据库,偶尔会丢掉一个线程。但大部分时候是正常。苦恼中。该怎么处理
多线程查询数据库,偶尔会丢掉一个线程。但大部分时候是正常。苦恼中。
如题。使用多个线程查询数据,然后汇总为1个数据集。偶尔会丢掉一个线程查询的数据集。
可能是什么原因呢。
代码很长,熟悉多线程的兄弟提示下,我贴相关的代码出来。
丢掉线程后,下次查询会出来如下错误。
'Access violation at address 770F4C27 in module 'oleaut32.dll'
没有丢掉线程时,无此错误提示。
一共就5个线程而已。
确实是很奇怪的问题。
我已经仔细检查了数据集,在少数情况(大概十几次中出现1次)
有1个线程的数据集丢失。所有代码如下
=====线程的代码==================
unit QueryThread;
interface
uses
Classes, Messages, Provider, ADODB, ActiveX;
const
WM_QueryDone = WM_User+1010;
type
TTag = 0..4;
TQueryThread = class(TThread)
private
FTag: TTag;
FHandle: THandle;
FQuery: TADOQuery;
function CreateSQL(const Tag: TTag): string;
protected
procedure Execute; override;
public
constructor Create(const ADataSetProvider: TDataSetProvider; ATag: TTag; AHandle: THandle);
end;
implementation
uses
Windows, Forms, SysUtils;
{ TQueryThread }
constructor TQueryThread.Create(const ADataSetProvider: TDataSetProvider;
ATag: TTag; AHandle: THandle);
begin
FTag := ATag;
FHandle := AHandle;
FQuery := TADOQuery.Create(nil);
FQuery.ConnectionString := ' Provider=SQLOLEDB.1;Password=111;Persist Security Info=True;User ID=sa;Initial Catalog=test'; //写入链接串
FQuery.SQL.Text := CreateSQL(FTag); //创建SQL语句
ADataSetProvider.DataSet := FQuery;
FreeOnTerminate := True;
inherited Create(False);
end;
function TQueryThread.CreateSQL(const Tag: TTag): string;
begin
case Tag of
0: Result := 'select top 5 * from VW_test where rq= ''2009-02-26 00:00:00.000''';
1: Result := 'select top 5 * from VW_test where rq= ''2009-02-27 00:00:00.000''';
2: Result := 'select top 5 * from VW_test where rq= ''2009-02-28 00:00:00.000''';
3: Result := 'select top 5 * from VW_test where rq= ''2009-03-01 00:00:00.000''';
4: Result := 'select top 5 * from VW_test where rq= ''2009-03-02 00:00:00.000''';
end;
end;
procedure TQueryThread.Execute;
begin
CoInitialize(nil);
try
FQuery.Open;
PostMessage(FHandle, WM_QueryDone, FTag, 0); //发送查询结束消息
finally
CoUnInitialize;
end;
end;
end.
=======================
====调试的代码==
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, DB, DBClient, Grids, DBGrids, Provider,
QueryThread,ADODB,Contnrs;
type
TMainForm = class(TForm)
BRefresh: TBitBtn;
CDSLocal: TClientDataSet;
CDSRemote_2: TClientDataSet;
CDSRemote_1: TClientDataSet;
CDSRemote_3: TClientDataSet;
CDSRemote_4: TClientDataSet;
DSPLocal: TDataSetProvider;
DSPRemote_1: TDataSetProvider;
DSPRemote_2: TDataSetProvider;
DSPRemote_3: TDataSetProvider;
DSPRemote_4: TDataSetProvider;
DSLocal: TDataSource;
DBGridLocal: TDBGrid;
ADOConnection1: TADOConnection;
BtnOneThread: TBitBtn;
DS_OneThread: TDataSource;
CDS_OneThread: TClientDataSet;
如题。使用多个线程查询数据,然后汇总为1个数据集。偶尔会丢掉一个线程查询的数据集。
可能是什么原因呢。
代码很长,熟悉多线程的兄弟提示下,我贴相关的代码出来。
丢掉线程后,下次查询会出来如下错误。
'Access violation at address 770F4C27 in module 'oleaut32.dll'
没有丢掉线程时,无此错误提示。
一共就5个线程而已。
确实是很奇怪的问题。
我已经仔细检查了数据集,在少数情况(大概十几次中出现1次)
有1个线程的数据集丢失。所有代码如下
=====线程的代码==================
unit QueryThread;
interface
uses
Classes, Messages, Provider, ADODB, ActiveX;
const
WM_QueryDone = WM_User+1010;
type
TTag = 0..4;
TQueryThread = class(TThread)
private
FTag: TTag;
FHandle: THandle;
FQuery: TADOQuery;
function CreateSQL(const Tag: TTag): string;
protected
procedure Execute; override;
public
constructor Create(const ADataSetProvider: TDataSetProvider; ATag: TTag; AHandle: THandle);
end;
implementation
uses
Windows, Forms, SysUtils;
{ TQueryThread }
constructor TQueryThread.Create(const ADataSetProvider: TDataSetProvider;
ATag: TTag; AHandle: THandle);
begin
FTag := ATag;
FHandle := AHandle;
FQuery := TADOQuery.Create(nil);
FQuery.ConnectionString := ' Provider=SQLOLEDB.1;Password=111;Persist Security Info=True;User ID=sa;Initial Catalog=test'; //写入链接串
FQuery.SQL.Text := CreateSQL(FTag); //创建SQL语句
ADataSetProvider.DataSet := FQuery;
FreeOnTerminate := True;
inherited Create(False);
end;
function TQueryThread.CreateSQL(const Tag: TTag): string;
begin
case Tag of
0: Result := 'select top 5 * from VW_test where rq= ''2009-02-26 00:00:00.000''';
1: Result := 'select top 5 * from VW_test where rq= ''2009-02-27 00:00:00.000''';
2: Result := 'select top 5 * from VW_test where rq= ''2009-02-28 00:00:00.000''';
3: Result := 'select top 5 * from VW_test where rq= ''2009-03-01 00:00:00.000''';
4: Result := 'select top 5 * from VW_test where rq= ''2009-03-02 00:00:00.000''';
end;
end;
procedure TQueryThread.Execute;
begin
CoInitialize(nil);
try
FQuery.Open;
PostMessage(FHandle, WM_QueryDone, FTag, 0); //发送查询结束消息
finally
CoUnInitialize;
end;
end;
end.
=======================
====调试的代码==
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, DB, DBClient, Grids, DBGrids, Provider,
QueryThread,ADODB,Contnrs;
type
TMainForm = class(TForm)
BRefresh: TBitBtn;
CDSLocal: TClientDataSet;
CDSRemote_2: TClientDataSet;
CDSRemote_1: TClientDataSet;
CDSRemote_3: TClientDataSet;
CDSRemote_4: TClientDataSet;
DSPLocal: TDataSetProvider;
DSPRemote_1: TDataSetProvider;
DSPRemote_2: TDataSetProvider;
DSPRemote_3: TDataSetProvider;
DSPRemote_4: TDataSetProvider;
DSLocal: TDataSource;
DBGridLocal: TDBGrid;
ADOConnection1: TADOConnection;
BtnOneThread: TBitBtn;
DS_OneThread: TDataSource;
CDS_OneThread: TClientDataSet;