unit main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.VCLUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, Vcl.StdCtrls, FireDAC.Phys.ADSDef, FireDAC.Phys.ASADef, FireDAC.Phys.DB2Def, FireDAC.Phys.FBDef, FireDAC.Phys.IBDef, FireDAC.Phys.InfxDef, FireDAC.Phys.MongoDBDef, FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLiteDef, FireDAC.Phys.PGDef, FireDAC.Phys.OracleDef, FireDAC.Phys.ODBCDef, FireDAC.Phys.MySQLDef, FireDAC.Phys.MSSQLDef, FireDAC.Phys.MSAccDef, FireDAC.Phys.TDataDef, FireDAC.Phys.TData, FireDAC.Phys.MSAcc, FireDAC.Phys.MSSQL, FireDAC.Phys.MySQL, FireDAC.Phys.ODBC, FireDAC.Phys.Oracle, FireDAC.Phys.PG, FireDAC.Phys.SQLite, FireDAC.Phys.MongoDB, FireDAC.Phys.Infx, FireDAC.Phys.IB, FireDAC.Phys.IBBase, FireDAC.Phys.FB, FireDAC.Phys.DB2, FireDAC.Phys.ODBCBase, FireDAC.Phys.ASA, FireDAC.Phys.ADS, Vcl.ExtCtrls; type TReadThread=class(TThread) FDConn: TFDConnection; protected procedure Execute; override; public Constructor Create(Conn: TFDConnection; SuspendedOnCreate: boolean); Overload; Destructor Destroy; Override; procedure Success; procedure Fail; end; TForm1 = class(TForm) Memo1: TMemo; Label1: TLabel; Edit1: TEdit; Button2: TButton; Button3: TButton; Button4: TButton; FDConn: TFDConnection; FDQuery1: TFDQuery; Advantage: TFDPhysADSDriverLink; ASE: TFDPhysASADriverLink; DB2: TFDPhysDB2DriverLink; Firebird: TFDPhysFBDriverLink; InterBase: TFDPhysIBDriverLink; Informix: TFDPhysInfxDriverLink; Mongo: TFDPhysMongoDriverLink; SQLite: TFDPhysSQLiteDriverLink; PosterSQL: TFDPhysPgDriverLink; Oracle: TFDPhysOracleDriverLink; ODBC: TFDPhysODBCDriverLink; MySQL: TFDPhysMySQLDriverLink; MSSQL: TFDPhysMSSQLDriverLink; MSAccess: TFDPhysMSAccessDriverLink; Teradata: TFDPhysTDataDriverLink; Edit2: TEdit; Label2: TLabel; Button1: TButton; procedure Button4Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } ConnCount: integer; Conns: array of TFDConnection; Threads: array of TReadThread; q: TFDQuery; t1,t2: integer; end; var Form1: TForm1; implementation {$R *.dfm} // // 建立對象... Constructor TReadThread.Create(Conn: TFDConnection; SuspendedOnCreate: boolean); begin Inherited Create(SuspendedOnCreate); freeOnTerminate:=true; FDConn:=Conn; end; // // 對象釋放... Destructor TReadThread.Destroy; begin Inherited Destroy; end; // // 成功+1.。。 procedure TReadThread.Success; begin inc(form1.t1); form1.edit1.Text:=inttostr(form1.t1); if form1.memo1.Lines.Count > 256 then form1.memo1.Lines.Clear; form1.Memo1.Lines.Add('線程'+inttostr(self.Handle)+': 讀取數據集成功!'); end; // // 失敗+1.。。 procedure TReadThread.Fail; begin inc(form1.t2); form1.edit2.Text:=inttostr(form1.t2); if form1.memo1.Lines.Count>256 then form1.memo1.Lines.Clear; form1.Memo1.Lines.Add('線程'+inttostr(self.Handle)+': *** 讀取數據集失敗!'); end; // // 線程主函數... procedure TReadThread.Execute; var q: TFDQuery; begin while not terminated do begin q:=TFDQuery.Create(nil); q.Connection:=FDConn; try q.SQL.Text:='Select * from tb_field order by Field_ID'; q.Active:=true; synchronize(success); Except synchronize(fail); end; FreeAndNil(q); sleep(100); end; end; procedure TForm1.Button1Click(Sender: TObject); var ConStr_Mysql: string; begin ConStr_Mysql := 'DriverID=MySQL;Database=test;Password=1234567;Server=192.168.6.28' + ';User_Name=root;port=3333;charset=utf8;WriteTimeout=300'; FDConn.ConnectionString := ConStr_Mysql; FDConn.Open(ConStr_Mysql); end; procedure TForm1.Button2Click(Sender: TObject); var ConStr_Mysql: string; i: integer; begin ConStr_Mysql := 'DriverID=MySQL;Database=test;Password=1234567;Server=192.168.6.28' + ';User_Name=root;port=3333;charset=utf8;WriteTimeout=300'; FDConn.ConnectionString := ConStr_Mysql; t1:=0; t2:=0; ConnCount:=10; setlength(Conns, ConnCount); setlength(Threads, ConnCount); for i := 0 to 9 do begin Conns[i]:=TFDConnection.Create(nil); Conns[i].LoginPrompt := false; Conns[i].ConnectionString := ConStr_Mysql; Conns[i].Connected := true; Memo1.Lines.Add('第' + inttostr(i+1) + '個對象鏈接服務器成功!'); Threads[i] := TReadThread.Create(conns[i], true); Threads[i].Resume; end; end; procedure TForm1.Button3Click(Sender: TObject); var i: integer; begin for i := 0 to 9 do begin Threads[i].Terminate; Memo1.Lines.Add('第'+inttostr(i+1)+'個線程對象中止!'); conns[i].Free; end; ConnCount:=0; setlength(Conns,ConnCount); setlength(Threads,ConnCount); end; procedure TForm1.Button4Click(Sender: TObject); begin close; end; end. ```