View Full Version : هنگ كردن برنامه
aradsystem
سه شنبه 01 اردیبهشت 1388, 17:51 عصر
دوستان سلام.
يه مشكلي توي برنامه هاي دلفي هست اينكه وقتي برنامه به يه حلقه ميرسه كه عملياتي (بانك اطلاعاتي) رو كه مثلا حدود 10 ثانيه طول ميكشه ميخواد انجام بده برنامه توي اين مدت يه حالتي مثل هنگ كردن براش پيش مياد. يعني كاربر فكر ميكنه كه برنامه قفل شده. طوري كه اگه يه كليك هم روي فرم برنامه بزنه روي كپشن فرم not responding.. ظاهر ميشه. براي برطرف كردن اين مشكل بايد چيكار كنم؟
با تشكر از همه دوستان.
merced
سه شنبه 01 اردیبهشت 1388, 18:55 عصر
Multi threading
شما بايد اون كار رو تو يه نخ جداگانه از نخ برنامه ات انجام بدي .
MSHService
سه شنبه 01 اردیبهشت 1388, 20:03 عصر
با اجازه بزرگان
پس از Application.ProcessMessages کی استفاده میشه؟
aradsystem
سه شنبه 01 اردیبهشت 1388, 20:29 عصر
Multi threading
شما بايد اون كار رو تو يه نخ جداگانه از نخ برنامه ات انجام بدي .
من در اين مورد اطلاعاتي ندارم. ميشه راهنمايي كنيد دقيقا بايد چيكار كنم؟. ممنون ميشم.
aradsystem
سه شنبه 01 اردیبهشت 1388, 20:31 عصر
با اجازه بزرگان
پس از Application.ProcessMessages کی استفاده میشه؟
با اينكار مشكل حالت هنگ كردن برنامه هم برطرف ميشه؟
vcldeveloper
سه شنبه 01 اردیبهشت 1388, 21:25 عصر
من در اين مورد اطلاعاتي ندارم. ميشه راهنمايي كنيد دقيقا بايد چيكار كنم؟
عبارت Thread را در تالار دلفی جستجو کنید.
پس از Application.ProcessMessages کی استفاده میشه؟
در حلقه هایی که در آنها یک سری پردازش صورت میگیره، ولی حجم پردازش به اندازه ایی نیست که نیاز باشه آن را در Thread جداگانه ایی انجام داد. Application.PorcessMessages اگر در داخل حلقه اجرا بشه، در هر بار اجرای حلقه، باعث میشه که برنامه پیام هایی که بهش رسیده را پردازش کنه، مثل رسم رابط کاربر، یا پاسخ به کلیک و غیره.
در مورد مشکل مطرح شده در این تاپیک، باید از Thread استفاده بشه، چون برای باز کردن یک جدول یا اجرای یک کوئری در بانک اطلاعاتی، برنامه فقط دستور مربوطه را به نرم افزار مدیریت بانک اطلاعاتی ارسال میکنه، و منتظر می ایسته تا از سرور جواب برسه، پس عملا سرعت جواب دادن به حجم داده های برگشت داده شده، شرایط سرور بانک اطلاعاتی، و شرایط رسانه انتقال (مثل شبکه) برمیگرده، و برنامه نمیتونه کار خاصی انجام بده، جز اینکه منتظر وایسته. برای منتظر بودن هم، اگر این انتظار در Thread اصلی رخ بده، طبیعی هست که همه کارهای آن Thread متوقف میشه، از جمله پاسخ داده به پیام های رسیده. برای همین هم از یک Thread جداگانه استفاده میشه، تا منتظر شدن برای جواب موجب بلوکه شدن اجرای Thread اصلی برنامه نشه.
aradsystem
جمعه 04 اردیبهشت 1388, 23:22 عصر
با سلام و تشکر مجدد.
من نحوه ی استفاده و کار با Thread رو با کمک اساتید و دوستای خوب از همین سایت یاد گرفتم.
فقط یه مشکل و یه سوال دارم. فرض کنید من 2 تا یونیت دارم و در یونیت اول می خوام کار اصلی برنامه و در یونیت دوم با استفاده از Thread عملیات پشتیبان گیری رو انجام بدم. اول اینکه حتما باید Thread ی که می خواد عملیات کپی یه فایل رو انجام بده در یک یونیت جداگانه باشه یا نه؟
دوم اینکه من موقع کلیک کاربر Thread دوم رو اجرا می کنم. حالا از کجا بفهمم کارش تموم شده. یعنی اون فایل کپی شده؟ از Thread.Suspended استفاده کردم ولی همیشه مقدارش صفر هست.
در یونیت دوم در Thread.Execute دستور کپی فایل رو نوشتم. اخرشم Exit.
ایا با همین دستور Exit برنامه میفهمه کار Thread تموم شده یا نه؟
و اینکه Thread.Suspended رو توی یه تایمر گذاشتم تا هر 1 ثانیه چک کنه. اینکار درسته یا نه؟
vcldeveloper
شنبه 05 اردیبهشت 1388, 01:32 صبح
اول اینکه حتما باید Thread ی که می خواد عملیات کپی یه فایل رو انجام بده در یک یونیت جداگانه باشه یا نه؟
خیر، لزومی نداره حتما در یک یونیت جداگانه باشه.
دوم اینکه من موقع کلیک کاربر Thread دوم رو اجرا می کنم. حالا از کجا بفهمم کارش تموم شده.
بعد از اتمام کارش، رویداد OnTerminate مربوط به آن Thread فراخوانی میشه.
در یونیت دوم در Thread.Execute دستور کپی فایل رو نوشتم. اخرشم Exit.
Exit نوشتید که چی بشه؟! وقتی به آخر اجرای Execute رسیده، دیگه Exit به چه کاری میاد؟! هر وقت اجرای متد Execute به اتمام برسه، یعنی کار Thread تمام شده.
اینکه Thread.Suspended رو توی یه تایمر گذاشتم تا هر 1 ثانیه چک کنه. اینکار درسته یا نه؟
اشتباه هست، Suspended برای این کار طراحی نشده.
aradsystem
شنبه 05 اردیبهشت 1388, 09:34 صبح
بعد از اتمام کارش، رویداد OnTerminate مربوط به آن Thread فراخوانی میشه.
چطوري و در كجا ازش استفاده كنم؟ در خود Thread يا در تايمر يا Thread اصلي برنامه؟ چطوري چكش كنم؟
با تشكر از شما.
vcldeveloper
شنبه 05 اردیبهشت 1388, 12:36 عصر
چطوري و در كجا ازش استفاده كنم؟ در خود Thread يا در تايمر يا Thread اصلي برنامه؟ چطوري چكش كنم؟
در Threadایی که Thread شما را فراخوانی کرده، که معمولا همون Thread اصلی هست. نیازی نیست شما آن را چک کنید. شما یک متد به رویداد OnTerminate مربوط به Threadایی که ساختید، اختصاص میدید، و هر زمان Thread شما کارش تمام شد، آن کدی که به OnTerminate اختصاص داده بودید، اجرا میشه.
اگر بعد از اتمام کار Thread نیازی به آن ندارید، و فقط قصدتان Free کردن آن Thread بعد از پایان کارش هست، خصوصیت FreeOnTerminate آن را True کنید، تا خودش بعد از پایان کارش Free شود، و نیازی نباشه که شما کاری انجام بدید.
aradsystem
شنبه 05 اردیبهشت 1388, 17:28 عصر
اقا من اين كار رو هم انجام دادم ولي نتونستم مشكل رو حل كنم.
اين كد رو در يونيت اول قرار دادم. تا Thread ي كه كارش كپي يك فايل هست رو فراخواني كنه.
var
T : MyThread;
begin
T := MyThread.Create(True);
T.FreeOnTerminate := True;
T.Resume;
end;
و اين كد هم Thread ي كه كارش كپي فايل مورد نظره. مي خوام بعد از اتمام كپي شدن فايل برنامه بسته بشه.
type
MyThread = Class(TThread)
private
procedure OnTerminate;
protected
procedure Execute; override;
end;
var
implementation
procedure MyThread.OnTerminate;
begin
application.terminate;
end;
procedure MyThread.Execute;
begin
CopyFile();
end;
اين كد رو هم توي يه تايمر گذاشتم نشد.
if MyThread.FreeOnTerminate=true then
application.terminate;
هميشه مقدارش صفر هست.
vcldeveloper
شنبه 05 اردیبهشت 1388, 18:08 عصر
عزیز جان، گفتم رویداد OnTerminate، نگفتم شما خودتون یک متد بسازید، و اسمش را بزارید OnTerminate!
procedure TForm1.ThreadOnTerminate(Sender: TObject)
begin
Application.Terminate;
end;
procedure TForm1.Button1Click;
var
T : MyThread;
begin
T := MyThread.Create(True);
T.FreeOnTerminate := True;
T.OnTerminate := ThreadOnTerminate;
T.Resume;
end;
اين كد رو هم توي يه تايمر گذاشتم نشد.
FreeOnTerminate را که قبل از Resume کردن Thread مقدارش را True کردید، خب طبیعی هست که کد شما همواره مقدار True برمیگردانه!
Delphi Coder
دوشنبه 07 اردیبهشت 1388, 17:55 عصر
چطوري و در كجا ازش استفاده كنم؟ در خود Thread يا در تايمر يا Thread اصلي برنامه؟ چطوري چكش كنم؟ البته روشی که جناب آقای کشاورز فرمودن منطقی تر به نظر میاد ولی من عادت به استفاده از روش دیگه ای دارم اون هم اینکه یه فیلد در کلاس Thread به اسم ThreadTerminated قرار میدم و قبل از خروج از OnExecute اون رو True میکنم.
(البته نه در مواقعی که FreeOnTerminate مقدارش True باشه :گیج:)
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.