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() 来获得相同的效果。

A​​DO 在内部使用 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;