PDA

View Full Version : حرفه ای: مشکل با ترد



sobhan1990
پنج شنبه 08 آبان 1393, 13:50 عصر
سلام
من یک ترد در دلفی نوشتم به صورت زیر:


unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.DBGrids, Data.DB,
Data.Win.ADODB, Vcl.StdCtrls;


type
myThread=class(TThread)
protected
// the main body of the thread
procedure Execute; override;
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
class var
adocon : TADOConnection;
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
T : myThread;
begin
T := myThread.Create(True);
T.FreeOnTerminate := True;
T.Resume;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
adocon := TADOConnection.Create(Application);
adocon.Provider := 'SQLOLEDB.1';
adocon.LoginPrompt := False;
adocon.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=mydb;Data Source=.;';

end;

{ myThread}

procedure myThread.Execute;
begin
inherited;
ShowMessage('before');
Form1.adocon.Open();
ShowMessage('after');
end;

end.




ولی در زمان اجرا فقط کد ShowMessage('before'); اجرا میشه و دو خط بعدی اجرا نمیشه. چون کانکشن من به اسکیوال وصل نمیشه و انتظار دارم که یک پیام خطا عدم اتصال ببینم و بعدش پیام ShowMessage('after'); اجرا بشه.
کسی میدونه مشکل کجاست؟
با تشکر

*جیگرم*
جمعه 09 آبان 1393, 03:22 صبح
شما مجاز به استفاده از دستور shwmessage در ترد نیستید و بایستی از توابع سینک استفاده کنید.
برای اتصال به بانک اطلاعات می بایست تمامی اتصالات و کامپوننتهای مربوطه در ترد ساخته شده و یا در ماژول قرار بگیرد و نه این که کانکشن در فرم اصلی باشه و در ترد اون رو فراخوانی کنید...
برای نمونه:

constructor TChatMemberThread.Create(Name: string);
begin
inherited Create(True);
FName := Name;
FreeOnTerminate := True;

FSession := TABSSession.Create(nil);
FSession.AutoSessionName := True;

FDatabase := TABSDatabase.Create(nil);
FDatabase.DatabaseName := 'db_' + Name + '_' + IntToStr(Random(1000));
FDatabase.DatabaseFileName := ExtractFilePath(Application.ExeName) + DataBaseFileName;
FDatabase.SessionName := FSession.SessionName;
FDatabase.MultiUser := True;
FDatabase.Open;

FTable := TABSTable.Create(nil);
FTable.SessionName := FSession.SessionName;
FTable.DatabaseName := FDatabase.DatabaseName;
FTable.TableName := 'Chat';
FTable.Open;
end;

destructor TChatMemberThread.Destroy;
begin
FTable.Free;
FDatabase.Free;
FSession.Free;
inherited;
end;

procedure TChatMemberThread.Execute;
var
I: Integer;
begin
for I := 0 to 20 do
begin
if Terminated then Exit;
if MainForm.tblChat.Active and MainForm.tblChat.Exists then
begin
FTable.AppendRecord([FName, RandomFrom(ChatMessages)]);
{ refreshing must be done in a synchronzied method since it will modify
the contents of the grid and the grid can only be modified from the main
VCL thread }
Synchronize(RefreshTable);
Sleep(Random(100));
end;
end;
end;

....

procedure TChatMemberThread.RefreshTable;
begin
MainForm.tblChat.Refresh;
end

sobhan1990
جمعه 09 آبان 1393, 16:42 عصر
سلام
ممنون بابت Reply
کدم را به صورت زیر تغییر دادم ولی متاسفانه باز هم نتیجه نمی گیرم. یا شاید برای رسیدن به نتیجه ای که من میخوام باید کار دیگه ای کنم!


unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.DBGrids, Data.DB,
Data.Win.ADODB, Vcl.StdCtrls;

type
TBeeper = class(TThread)
public
function BoolToStr(Val : Boolean): String;
procedure connect;
class var
adocon : TADOConnection;
protected
procedure Execute; override;
end;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public

{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
T : TBeeper;
begin
T := TBeeper.Create(True);
T.FreeOnTerminate := True;
T.Resume;
end;

procedure TBeeper.connect;
begin
ShowMessage(BoolToStr(adocon.Connected));
end;

procedure TBeeper.Execute;
begin
inherited;
adocon := TADOConnection.Create(Application);
adocon.Provider := 'SQLOLEDB.1';
adocon.LoginPrompt := False;
adocon.ConnectionString := 'Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=mydb;Data Source=.;';

adocon.Open();
Synchronize(connect);
end;

function TBeeper.BoolToStr(Val: Boolean): String;
begin
if val = True then
result := 'True'
else
result := 'False';
end;

end.


من میخوام که به دیتابیس مورد نظرم کانکشن بزنم و سپس وضعیت کانکشن رو ببینم(حالا چه وصل باش و یا چه قطع؛ وضعیت رو می خوام بدونم) ولی روی دکمه که کلیک می کنم هیچ پاسخ یا واکنشی از برنامه نمی بینم.
سپاس فراوان

sobhan1990
شنبه 10 آبان 1393, 01:59 صبح
واقعا کسی نیست بدونه مشکل کار کجاس؟؟؟؟؟