PDA

View Full Version : Thread به زبان ساده !



Emdad2001
یک شنبه 26 آذر 1391, 21:27 عصر
سلام من در مورد Thread خیلی مطلب خوندم هم اینجا هم جاهای دیگه ولی از آخر به چند سوال برخوردم که نتونستم پیدا کنم :(

چرا میگن از Thread مستقیم از اشیاء روی فرم استفاده نکنیم ؟!!
اگه مستقیم استفاده نکنیم پس چجوری از آنها استفاده کنیم؟
مثال: TidHttp1 روی فرم رو چجوری بیاریم توی یونیت Thread ؟
__________________________________________________ ___

کسی میتونه به زبان ساده یعنی زیر دیپلم توضیح بده ؟

لطفا لینک ندین چون من همه این سایت را جستجو کردم آموزش آقای کشاورز را هم دیدم ولی بازم نتیجه نگرفتم شاید من خیلی ابتدایی هستم نمیدونم

mohsen24000
یک شنبه 26 آذر 1391, 21:37 عصر
چرا میگن از Thread مستقیم از اشیاء روی فرم استفاده نکنیم ؟!!
اگه مستقیم استفاده نکنیم پس چجوری از آنها استفاده کنیم؟
مثال: TidHttp1 روی فرم رو چجوری بیاریم توی یونیت Thread ؟

برای فریز نشدن برنامه
Synchronize(DoProgress);

var http: TIdHTTP;
begin
http:= TIdHTTP.Create(nil);
end;

Felony
یک شنبه 26 آذر 1391, 22:07 عصر
چرا میگن از Thread مستقیم از اشیاء روی فرم استفاده نکنیم ؟!!
چون Thread Safe نیستن .


اگه مستقیم استفاده نکنیم پس چجوری از آنها استفاده کنیم؟
راحت ترین راه برای تازه واردها تو این مباحث استفاده از Synchronize هست که تابع پاس داده شده رو در Context ترد اصلی برنامه اجرا میکنه و دیگه کمکی در فریز نشدن رابط کاربری بهتون نمیکنه ، اگر هم هدف جلوگیری از فریز شدن رابط کاربری هست که راحت ترین و سریعترین راه استفاده از پیغام ها هست که بارها در موردش صحبت شده ( SendMessage , PostMessage ) .

Emdad2001
یک شنبه 26 آذر 1391, 23:23 عصر
مرسی از اینکه جواب داید ولی من اول امتحان کردم روش آقا محسن را چون جواب نگرفتم این پست رو ایجاد کردم من دوتا Unit باز کردم ,Unit1 فرم اصلی برنامه هستش و Unit2 ، از فایل های خود دلفی استفاده کردم Thread هستش حالا توی Unit2 کد پایین رو نوشتم ولی Error میده

type
MyThread = class(TThread)
private
procedure DoProgress;
protected
procedure Execute; override;
end;

implementation

Procedure MyThread.DoProgress;
var
MDream:TMemoryStream;
http:TidHttp;
begin
try
MDream:=TMemoryStream.Create;
http:=Tidhttp.create(nil);
http.get('http://www.example.com',MDream);
MDream.SaveToFile('C:\test.exe');
finally
MDream.Free;
http.free;
end;
end;

procedure MyThread.Execute;
begin
Synchronize(DoProgress);
end;

end.

اما خطا! دلفی این هستش

[DCC Error] Unit2.pas(21): E2003 Undeclared identifier: 'TidHttp'
[DCC Error] Unit2.pas(25): E2066 Missing operator or semicolon
[DCC Error] Unit2.pas(26): E2066 Missing operator or semicolon
[DCC Error] Unit2.pas(30): E2066 Missing operator or semicolon
[DCC Fatal Error] Project1.dpr(6): F2063 Could not compile used unit 'Unit2.pas'
Failed

mohsen24000
یک شنبه 26 آذر 1391, 23:29 عصر
یونیت IdHTTP را به uses اضافه کنید...
در ضمن اون Synchronize لزومی نداره!

Emdad2001
دوشنبه 27 آذر 1391, 00:07 صبح
یونیت IdHTTP را به uses اضافه کنید...
در ضمن اون Synchronize لزومی نداره!

ججوری اجرا کنم؟! من اونجا Sync کردم بعد توی Unit1
Unit2 رو uses کردم تا به Thread دسترسی داشته باشم بعد با دستور MyThread.Create اجرا کردم اما متاسفانه برنامه هنگ میکنه ؟؟!!

mohsen24000
دوشنبه 27 آذر 1391, 00:16 صبح
این یه نمونه یونیته که تقریبا کاری که میخواید رو انجام میده:

unit upost_thread;

interface

uses
Classes,windows,sysutils,dialogs , IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdHTTP;

type
http_post = class(TThread)
private
FEvent : THandle;
procedure DoTheJob;
procedure Execute; override;
public
constructor Create(Suspended: Boolean);
destructor Destroy; override;
procedure NotifyThread;
procedure StopThread;
end;

implementation

uses Uappmain;

constructor http_post.Create(Suspended: Boolean);
begin
inherited;
FEvent := CreateEvent(nil,True,False,'');
end;

destructor http_post.Destroy;
begin
CloseHandle(FEvent);
inherited;
end;

procedure http_post.StopThread;
begin
Terminate;
SetEvent(FEvent);
WaitFor;
end;

procedure http_post.DoTheJob;
var
Params: TStringlist;
resp: TStringStream;
http: TIdHTTP;
begin
try
Params := TSTringList.Create;
resp := TStringStream.Create('');
http:= TIdHTTP.Create(nil);
Params := TStringlist.create;
params.Values['app']:='ELib';
params.Values['action']:='log';
with HTTP do
begin
HandleRedirects := True;
AllowCookies := True;
Request.ContentType := 'application/x-www-form-urlencoded';//'text/html';
Request.AcceptCharSet := 'utf-8';
Request.UserAgent := '';//'agent2';
Request.Connection := 'Keep-Alive';
Request.ProxyConnection := 'Keep-Alive';
Request.CacheControl := 'no-cache';
post('http://domain.ir/a.php',params,resp);
frmApp.resp:=resp.DataString;
end;
finally
params.Free;
resp.Free;
end;
StopThread;
end;

procedure http_post.Execute;
begin
while not Terminated do
begin
if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then
DoTheJob;
end;
end;

procedure http_post.NotifyThread;
begin
PulseEvent(FEvent);
end;
end.

نحوه فراخوانی:

Private
postThread:http_post;
...
postThread := http_post.Create(True);
postThread.FreeOnTerminate := True;
postThread.Resume;
...
postThread.NotifyThread;

Emdad2001
دوشنبه 27 آذر 1391, 00:26 صبح
به قول خودتون Copy & paste خوب نیست ! ولی منم دوست دارم یاد بگیرم نه اینکه کارم انجام بشه شما لطف دارین همه رو اماده نوشتین ولی اینجوری یکی دیگه مثل من پیدا میشه دوباره همین سوال ها رو می پرسه خوب برای اونم میخواین یک کد دیگه بنویسین به نظر من اگه ماهی گیری یاد بدین بهتره تا ماهی بدین دستشون

Emdad2001
پنج شنبه 07 دی 1391, 14:52 عصر
مرسی، من کد شما استفاده کردم باید از شما تشکر کنم که با این کدی که دادید من یک چیزهایی متوجه شدم حالا لطفا میکنید بگید چطور وسط کار این Thread رو Stop کنم ؟ !

mohsen24000
پنج شنبه 07 دی 1391, 15:02 عصر
در اون کد تابعی تعریف شده برای متوقف کردن ترید: StopThread

Emdad2001
پنج شنبه 07 دی 1391, 15:45 عصر
در اون کد تابعی تعریف شده برای متوقف کردن ترید: StopThread

بله دیدم منظور شما کد پایین هستش ولی شما اینو در انتها گذاشین یعنی وقتی که کار تمام شد. خوب حالا من روی فرم Button Cancel هم دارم همین که Cancel رو میزنم برنامه رو میبندم یعنی Thread هم Stop میشه ؟ برای Cancel هم از این کدها استفاده کردم Tidhttp.free, TStringStream.free, Self.Close

procedure http_post.StopThread;
begin
Terminate;
SetEvent(FEvent);
WaitFor;
end