TADOConnection 与 SQL 服务器线程与 Delphi
TADOConnection with SQL Server Thread with Delphi
我正在做一个项目,我需要考虑紧急情况。
主要问题是,如何检查数据库是否已连接(圆圈对象=红色或绿色)?
BeforeConnect
,AfterDisconnect
,他们没有好的答案。
内部类型:
创建连接:
procedure TForm1.Button1Click(Sender: TObject);
var
s : String;
begin
ADOConnectionSQL := TADOConnection.Create(nil);
ADOConnectionSQL.LoginPrompt := false;
with ADOSQL do
begin
s := 'Provider=SQLNCLI11.1;'+
'Persist Security Info=False;'+
'User ID='+Edit1.Text+';'+
'Initial Catalog='+Edit2.Text+';'+
'Data Source='+Edit3.Text+';'+
'Initial File Name="";'+
'Server SPN="";'+
'password="'+Edit4.Text+'"';
ADOConnectionSQL.ConnectionString := s;
end;
ADOConnectionSQL.BeforeConnect := SQLConnected;
ADOConnectionSQL.AfterDisconnect := SQLDisconnected;
end;
尝试连接:
procedure TForm1.Button2Click(Sender: TObject);
var
Thread : TThread;
begin
Thread := TThread.CreateAnonymousThread(
procedure
begin
TThread.Synchronize(TThread.CurrentThread,
procedure
begin
try
ADOConnectionSQL.Connected := True;
ADOConnectionSQL.Open;
except
on E: Exception do
begin
ShowMessage('Exception message = '+E.Message);
end;
end;
ADOQuerySQL := TADOQuery.Create(nil);
end);
end);
Thread.OnTerminate := FinishConnected;
Thread.Start;
end;
绿色或红色:
procedure TForm1.SQLConnected(Sender: TObject);
begin
Circle1.Fill.Color := $FF00FF00;
end;
procedure TForm1.SQLDisconnected(Sender: TObject);
begin
Circle1.Fill.Color := $FFFF0000;
end;
完成连接:
procedure TForm1.FinishConnected(Sender: TObject);
begin
if TThread(Sender).FatalException <> nil then
begin
// something went wrong
ShowMessage ('Failure to connection');
//Exit;
end;
end;
当SQL服务器在线时,我希望看到一个绿色圆圈。当与服务器的连接中断时,圆圈应该是红色的。
您正在主 UI 线程的上下文中创建和打开 ADO 连接,而不是在辅助线程的上下文中。所以你的工作线程基本上是没用的。您可以直接使用 TThread.ForceQueue()
来获得相同的效果。
ADO 在内部使用 COM 技术,因此无论如何您都不能真正跨线程边界使用它。如果要在线程中使用 ADO,请为线程提供它自己的 ADO Connection 和 Query 对象。在线程上下文中完成所有 SQL 工作,并根据需要与主 UI 线程同步状态更新。
此外,您需要先在工作线程中初始化 COM 库,然后才能使用 ADO。
尝试更像这样的东西:
procedure TForm1.Button1Click(Sender: TObject);
var
Thread : TThread;
ConnStr: string;
begin
ConnStr := 'Provider=SQLNCLI11.1;'+
'Persist Security Info=False;'+
'User ID='+Edit1.Text+';'+
'Initial Catalog='+Edit2.Text+';'+
'Data Source='+Edit3.Text+';'+
'Initial File Name="";'+
'Server SPN="";'+
'password="'+Edit4.Text+'"';
Thread := TThread.CreateAnonymousThread(
procedure
var
ADOConnectionSQL: TADOConnection;
ADOQuerySQL: TADOQuery;
begin
CoInitialize(nil);
try
ADOConnectionSQL := TADOConnection.Create(nil);
try
ADOConnectionSQL.LoginPrompt := False;
ADOConnectionSQL.ConnectionString := ConnStr;
ADOConnectionSQL.Open;
TThread.Queue(nil,
procedure
begin
Circle1.Fill.Color := TAlphaColorRec.Green;
end
);
ADOQuerySQL := TADOQuery.Create(nil);
try
ADOQuerySQL.Connection := ADOConnectionSQL;
// use ADOQuerySQL as needed...
finally
ADOQuerySQL.Free;
end;
finally
ADOConnectionSQL.Free;
end;
finally
CoUninitialize;
end;
end);
Thread.OnTerminate := SQLFinished;
Thread.Start;
end;
procedure TForm1.SQLFinished(Sender: TObject);
begin
Circle1.Fill.Color := TAlphaColorRec.Red;
if TThread(Sender).FatalException <> nil then
begin
// something went wrong
ShowMessage('Failure! ' + Exception(TThread(Sender).FatalException).Message);
end;
end;
我正在做一个项目,我需要考虑紧急情况。
主要问题是,如何检查数据库是否已连接(圆圈对象=红色或绿色)?
BeforeConnect
,AfterDisconnect
,他们没有好的答案。
内部类型:
创建连接:
procedure TForm1.Button1Click(Sender: TObject);
var
s : String;
begin
ADOConnectionSQL := TADOConnection.Create(nil);
ADOConnectionSQL.LoginPrompt := false;
with ADOSQL do
begin
s := 'Provider=SQLNCLI11.1;'+
'Persist Security Info=False;'+
'User ID='+Edit1.Text+';'+
'Initial Catalog='+Edit2.Text+';'+
'Data Source='+Edit3.Text+';'+
'Initial File Name="";'+
'Server SPN="";'+
'password="'+Edit4.Text+'"';
ADOConnectionSQL.ConnectionString := s;
end;
ADOConnectionSQL.BeforeConnect := SQLConnected;
ADOConnectionSQL.AfterDisconnect := SQLDisconnected;
end;
尝试连接:
procedure TForm1.Button2Click(Sender: TObject);
var
Thread : TThread;
begin
Thread := TThread.CreateAnonymousThread(
procedure
begin
TThread.Synchronize(TThread.CurrentThread,
procedure
begin
try
ADOConnectionSQL.Connected := True;
ADOConnectionSQL.Open;
except
on E: Exception do
begin
ShowMessage('Exception message = '+E.Message);
end;
end;
ADOQuerySQL := TADOQuery.Create(nil);
end);
end);
Thread.OnTerminate := FinishConnected;
Thread.Start;
end;
绿色或红色:
procedure TForm1.SQLConnected(Sender: TObject);
begin
Circle1.Fill.Color := $FF00FF00;
end;
procedure TForm1.SQLDisconnected(Sender: TObject);
begin
Circle1.Fill.Color := $FFFF0000;
end;
完成连接:
procedure TForm1.FinishConnected(Sender: TObject);
begin
if TThread(Sender).FatalException <> nil then
begin
// something went wrong
ShowMessage ('Failure to connection');
//Exit;
end;
end;
当SQL服务器在线时,我希望看到一个绿色圆圈。当与服务器的连接中断时,圆圈应该是红色的。
您正在主 UI 线程的上下文中创建和打开 ADO 连接,而不是在辅助线程的上下文中。所以你的工作线程基本上是没用的。您可以直接使用 TThread.ForceQueue()
来获得相同的效果。
ADO 在内部使用 COM 技术,因此无论如何您都不能真正跨线程边界使用它。如果要在线程中使用 ADO,请为线程提供它自己的 ADO Connection 和 Query 对象。在线程上下文中完成所有 SQL 工作,并根据需要与主 UI 线程同步状态更新。
此外,您需要先在工作线程中初始化 COM 库,然后才能使用 ADO。
尝试更像这样的东西:
procedure TForm1.Button1Click(Sender: TObject);
var
Thread : TThread;
ConnStr: string;
begin
ConnStr := 'Provider=SQLNCLI11.1;'+
'Persist Security Info=False;'+
'User ID='+Edit1.Text+';'+
'Initial Catalog='+Edit2.Text+';'+
'Data Source='+Edit3.Text+';'+
'Initial File Name="";'+
'Server SPN="";'+
'password="'+Edit4.Text+'"';
Thread := TThread.CreateAnonymousThread(
procedure
var
ADOConnectionSQL: TADOConnection;
ADOQuerySQL: TADOQuery;
begin
CoInitialize(nil);
try
ADOConnectionSQL := TADOConnection.Create(nil);
try
ADOConnectionSQL.LoginPrompt := False;
ADOConnectionSQL.ConnectionString := ConnStr;
ADOConnectionSQL.Open;
TThread.Queue(nil,
procedure
begin
Circle1.Fill.Color := TAlphaColorRec.Green;
end
);
ADOQuerySQL := TADOQuery.Create(nil);
try
ADOQuerySQL.Connection := ADOConnectionSQL;
// use ADOQuerySQL as needed...
finally
ADOQuerySQL.Free;
end;
finally
ADOConnectionSQL.Free;
end;
finally
CoUninitialize;
end;
end);
Thread.OnTerminate := SQLFinished;
Thread.Start;
end;
procedure TForm1.SQLFinished(Sender: TObject);
begin
Circle1.Fill.Color := TAlphaColorRec.Red;
if TThread(Sender).FatalException <> nil then
begin
// something went wrong
ShowMessage('Failure! ' + Exception(TThread(Sender).FatalException).Message);
end;
end;