PDA

View Full Version : Sleep



hajibandeh
دوشنبه 15 مهر 1387, 09:49 صبح
با سلام به دوستان
من در حال نوشتن یه برنامه صنعتی هستم
در برخی از پروسه های این برنامه لازم است که پروسه بدون ایجاد تداخل بین پروسه های دیگر به مدت زمانهای مختلف صبر کند .
من در اینجا از متد Sleep استفاده کردم
ولی این متد باعث میشود کل برنامه متوقف شود
سوال من از دوستان این است که ایا متدی میتوان به جای Sleep به کار بست که کل برنامه متوقف نشود ؟
در ضمن جستجو هم کردم نتیجه ای نگرفتم

از دوستان صاحب نظر خواهش میکنم کمک کنند

hajibandeh
دوشنبه 15 مهر 1387, 10:08 صبح
procedure TForm1.Run;
begin
CheckBox1.Checked:=True;
Sleep(1000)
CheckBox1.Checked:=False;
End;

hajibandeh
دوشنبه 15 مهر 1387, 10:24 صبح
دوستان کسی نیست که جواب را بدونه

hajibandeh
دوشنبه 15 مهر 1387, 10:43 صبح
دوستان کسی نیست که جواب را بدونه
دوستان سوال فوریه

vcldeveloper
دوشنبه 15 مهر 1387, 11:03 صبح
Sleep سرنخ (Thread) جاری را به مدت زمان مشخص شده Idle میکنه. اگر برنامه شما تک سرنخه باشه، با فراخوانی Sleep تنها سرنخ برنامه شما Idle میشه، یعنی تا زمانی که براش تعیین کردید، کدی از اون اجرا نمیشه. پس در این مدت رابط کاربر هم که همیشه از طریق سرنخ اصلی برنامه بروز میشه، امکان بروز شدن پیدا نمیکنه. برای اینکه اجرای کد مربوطه متوقف بشه، ولی رابط کاربر همچان بروز بشه، دو راه دارید:
1- کدهای مورد نظر را به یک سرنخ جدید منتقل کنید و برنامه را بصورت Multi-threaded بنویسید.
2- بجای Sleep از یک حلقه استفاده کنید که به مدت معینی ادامه پیدا کند و در آن فقط Application.ProcessMessage فراخوانی شود.

hajibandeh
سه شنبه 16 مهر 1387, 08:24 صبح
روش Thread را قبلا امتحان کرده بودم ولی جواب نمیده
به دلیل اینکه Execute ترد را باید یه جایی فراخوانی بکنم همونجا برنامه قفل میکنه
البته شاید من اشتباه کرده باشم
کد مربوطه را میزارم تا نظر بدید

hajibandeh
سه شنبه 16 مهر 1387, 08:25 صبح
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
MyThread=Class(TThread)
private
public
procedure Execute; override;
end;
type
TForm1 = class(TForm)
Timer1: TTimer;
Label1: TLabel;
Button1: TButton;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Cou1,Cou2:Integer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Inc(Cou1);
Self.Caption:=IntToStr(Cou1);
end;
{ MyThread }
procedure MyThread.Execute;
var
I:Integer;
begin
inherited;
for i:=0 to 10 do
begin
Inc(Form1.Cou2);
Sleep(1000);
Form1.Label1.Caption:=IntToStr(Form1.Cou2)
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
T:MyThread;
begin
T:=MyThread.Create(True);
T.Priority:=tpNormal;
T.Execute;
end;
end.

hajibandeh
سه شنبه 16 مهر 1387, 08:35 صبح
البته یک Procedure نوشتم که مشابه Sleep عمل میکنه ولی زمانیکه این پروسیجر در حال اعمال تاخیر 50 درصد CPU اشغال میشه


Uses DateUtils;

procedure Wait(MiliSeconde:Cardinal);

procedure TForm1.Wait(MiliSeconde: Cardinal);
var
T1,T2:Longint;
D:TTime;
begin
D:=Now;
T1:=(( SecondOf(D) + (MinuteOf(D) * 60) + (HourOf(D) * 3600))* 1000)+MilliSecondOf(D)+(MiliSeconde-1);
while T2<T1 do
begin
D:=Now;
T2:=(( SecondOf(D) + (MinuteOf(D) * 60) + (HourOf(D) * 3600))* 1000)+MilliSecondOf(D);
Application.ProcessMessages;
end;
end;

Cave_Man
سه شنبه 16 مهر 1387, 09:45 صبح
فکر میکنم برای این کار بهترین راه استفاده از Timer هست با استفاده از تایمر با این مشکلاتی که الان مواجه هستید دیگه روبرو نخواهید شد

hajibandeh
سه شنبه 16 مهر 1387, 09:57 صبح
اگر بخوام از تایمر استفاده کنم باید بیش از 1000 تایمر بزارم تازه مدیریتش هم سخت میشه

hajibandeh
سه شنبه 16 مهر 1387, 12:05 عصر
کسی نمیدونه چیکار میشه کرد

Mahmood_M
سه شنبه 16 مهر 1387, 23:32 عصر
مشکل کد Thread شما در این قسمت هست ( به خاطر همین قفل میکنه ) :

procedure MyThread.Execute;
var
I:Integer;
begin
inherited;
for i:=0 to 10 do
begin
Inc(Form1.Cou2);
Sleep(1000);
Form1.Label1.Caption:=IntToStr(Form1.Cou2)
end;
end;

دسترسی به فرمها و در کل کامپوننتهای VCL باید با Synchronize انجام بشه ، در باره Synchronize و یا Thread در سایت مقاله و بحث زیاد هست ، جستجو کنید مشکلتون حل میشه ...

موفق باشید ...

vcldeveloper
چهارشنبه 17 مهر 1387, 01:04 صبح
خب، هدف از این Thread چی هست؟! اینکه فقط خودش را یک ثانیه متوقف میکنه! اگر می خواید از Thread استفاده کنید، باید پردازشتان هم در اون Thread انجام بشه، تا زمانی که Thread متوقف میشه، پردازش شما هم متوقف بشه. اگر قرار باشه که پردازش در همون Thread اصلی انجام بشه که این Thread دومی هیچ کاربردی نداره!
در ضمن، قبلا هم گفتم که رابط کاربر فقط از طریق Thread اصلی باید تغییر کنه، یا بهتر هست بگیم که هر کنترلی که در یک Thread ساخته میشه، فقط و فقط باید توسط همون Thread تغییر کنه. چون کنترل های رابط کاربر در Thread اصلی ساخته میشند، باید هم توسط همان Thread تغییر کنند. برای اینکه به Thread اصلی بفهمانید که لازم هست تغییری در رابط کاربر اعمال کنه، راههای مختلفی وجود داره، مثل استفاده از متد Synchronize یا ارسال پیام به Thread اصلی، Event و... به مجموعه این کارها میگن Thread Synchronization.

hajibandeh
شنبه 20 مهر 1387, 07:51 صبح
کجای این تردی که من ساختم اشکال داره
چرا هنگامی که سرنخ ترد Sleep میشه همه برنامه قفل میکنه

ariobarzan
شنبه 20 مهر 1387, 13:05 عصر
برنامه صنعتي كه اشاره كرديد از چه سخت افزاري استفاده ميكنه؟
بعضي كارتهاي كنترلي خودشون تايمر دارند و پارامتر ها رو از طريق برنامه دريافت ميكنند
مثلا كارتهاي كنترلي Advantech
نمايندگي اون هم شركت پتسا صنعته
بعضي وقت ها بد نيست كه يه كم از كار ها رو به عهده سخت افزار قرار بديم
معمولا كاري كه با تايمر سر و كار داره دقيق جواب نميده.

hajibandeh
دوشنبه 22 مهر 1387, 11:38 صبح
سخت افزار این برنامه ساخت خودمه
و قرار یک کارخانه تولید خوراک دام را کنترل کنه
ارتباط سخت افزار و نر افزار از طریق RS232 انجام میشه
این سخت افزار وظیفه اعمال خروجی و ورودی را بعهده داره و نمیشه از تایمرهای داخلی اون بهره گرفت

معمولا كاري كه با تايمر سر و كار داره دقيق جواب نميده
در برخی موارد لازمه که پروسه برای مدت تعین شده متوقف تا اعمال به صورت کامل انجام شود