PDA

View Full Version : سفید شدن فرم هنگاه انجام کار سنگین



captain_black81
دوشنبه 18 آبان 1388, 17:44 عصر
سلام دوستان

من یه پروژه دارم که توش یه کار سنگین میکنه مثلا یه دیتا گرید 20000 خطی رو ذخیره میکنه

اما موقع اجرا اگه رو فرم کلیک کنی سفید میشه و هیچ کنترلی روش نداری

بفرض من میخوام کنار progress bar اسم شخصی که داره ذخیره میشه نشون بدم (یه چیزی شبیه نصب بازی که اسم فایلا رو نشون میده) ولی کنترل lable تکون نمیخوره و اگه هم کلیک کنم صفحه سفید میشه

میشه راهنمایی کنید؟

Amir Oveisi
دوشنبه 18 آبان 1388, 18:13 عصر
باید از Multi Threading استفاده کنید. جستجو کنید در سایت.

Mostafa_Dindar
دوشنبه 18 آبان 1388, 18:19 عصر
حتي اگه ProgressBar هم بزاري و مشكلت رو حل كني بازم كارت درست نيست !!!
شما نبايد اون همه ركورد رو لود كني . اصطلاحا بايد Paging كني يعني به اندازه نيازت از ديتابيس بخوني

taeb1986
دوشنبه 18 آبان 1388, 20:51 عصر
دوست عزیز به عنوان یک راه حل ساده پیشنهاد میکنم که از کنترل timer استفاده بکنید،یعنی به جای این که مثلا در یک حلقه که از یک تا 20000 میشمارد رکوردها را بازیابی کنید،در event مربوط به تایمر(tick)،این کار را انجام بدهید،برای کنترل شمارش هم میتوانید متغیری سراسری در برنامه داشته باشید که مقدار اولیه صفر داشته باشد و با هر بار tick تایمر،یک واحد اضافه شود،و وقتی به رقم مورد نظر رسید متوقف شود(timer.stopالبته تایمر بایدقبلا در ابتدای برنامه استارت شده باشدtimer.start)،ضمنا interval کنترل تایمر به صورت پیش فرض 100 است که حتما باید آنرا پایین بیاورید تا برنامه کند اجرا نشود(میزان بهینه تر آنرا با چند بار اجرای برنامه با مقادیر مختلف میتوانید حدس بزنید)،به این ترتیب به احتمال زیاد مشکلتان حل میشود،ولی جهت اطمینان بیشتر از به قول شما سفید نشدن فرم،بهتر است در هر چند بار اجرای tick،(مثلابه ازای هر 30 بار)یکبار فرم را refresh کنید،به اینصورت()form.refresh.

esmartiz_red
سه شنبه 19 آبان 1388, 02:26 صبح
باید از Multi Threading استفاده کنید. جستجو کنید در سایت.

منم موافقم بهترین روش همینه

M.YasPro
سه شنبه 19 آبان 1388, 08:37 صبح
سلام
در تکمیل حرف دوستمون Bermoda میتونی از

cmd.BeginExecuteNonQuery();

cmd.EndExecuteNonQuery();
استفاده کنی البته با یه کم تلاش
اگه خواستی بگو نمونه بزارم .

Happy_davood
سه شنبه 19 آبان 1388, 11:32 صبح
برای حل مشکل دو تا کار میشه کرد .
اولاً اگه از حلقه استفاده می کیند باید وسط ، ابتدا یا انتهای حلقه از دستور Apllication.DoEvents استفاده کنید .
اگر هم حلقه نیست و مثلاً یه پردازش زمانبر در سمت بانک اصلاعاتی هست (یا هر پردازش دیگه ای) باید از BackroundWorker استفاده بشه . هر دوی این روش ها اصولی و انجامش هم ساده هست .

علت سفید شدن برنامه هم برمی گرده به اصول برنامه نویسی در ویندوز . وقتی برنامه سرگرم انجام پردازش بزرگی هست فرصت نمیکنه به ایونت WM_Paint جواب بده . بنابراین صفحه Refresh نمیشه و همه جا سفید دیده میشه . با فراخوانی تابع Application.DoEvents شما این فرصت رو به برنامه می دید که به ایونت های موجود در ApplicationQueue سری بزنه و قسمتی از اونها رو انجام بده از جمله همین WM_PAINT رو ککه باعث Refresh شدن ظاهر برنامه میشه .

captain_black81
چهارشنبه 20 آبان 1388, 14:24 عصر
دوست عزیز به عنوان یک راه حل ساده پیشنهاد میکنم که از کنترل timer استفاده بکنید،یعنی به جای این که مثلا در یک حلقه که از یک تا 20000 میشمارد رکوردها را بازیابی کنید،در event مربوط به تایمر(tick)،این کار را انجام بدهید،برای کنترل شمارش هم میتوانید متغیری سراسری در برنامه داشته باشید که مقدار اولیه صفر داشته باشد و با هر بار tick تایمر،یک واحد اضافه شود،و وقتی به رقم مورد نظر رسید متوقف شود(timer.stopالبته تایمر بایدقبلا در ابتدای برنامه استارت شده باشدtimer.start)،ضمنا interval کنترل تایمر به صورت پیش فرض 100 است که حتما باید آنرا پایین بیاورید تا برنامه کند اجرا نشود(میزان بهینه تر آنرا با چند بار اجرای برنامه با مقادیر مختلف میتوانید حدس بزنید)،به این ترتیب به احتمال زیاد مشکلتان حل میشود،ولی جهت اطمینان بیشتر از به قول شما سفید نشدن فرم،بهتر است در هر چند بار اجرای tick،(مثلابه ازای هر 30 بار)یکبار فرم را refresh کنید،به اینصورت()form.refresh.


ممنون دوست من ولی مشکل من این نیست
اضافه کردن تایمر هم یعنی بار بیشتر رو برنامه و غوز بالا غوز

captain_black81
چهارشنبه 20 آبان 1388, 14:25 عصر
با فراخوانی تابع Application.DoEvents شما این فرصت رو به برنامه می دید که به ایونت های موجود در ApplicationQueue سری بزنه و قسمتی از اونها رو انجام بده از جمله همین WM_PAINT رو ککه باعث Refresh شدن ظاهر برنامه میشه .

ممنون دوست من
اما اگه این تابعو اول و آخر حلقه بذارم که بدرد نمیخوره
من توی حلقه میخوام فرمم نمایش داده بشه

captain_black81
چهارشنبه 20 آبان 1388, 14:26 عصر
با فراخوانی تابع Application.DoEvents شما این فرصت رو به برنامه می دید که به ایونت های موجود در ApplicationQueue سری بزنه و قسمتی از اونها رو انجام بده از جمله همین WM_PAINT رو ککه باعث Refresh شدن ظاهر برنامه میشه .

ممنون
ولی اول و آخر حلقه که بدرد نمیخوره
من میخوام در طی حلقه سفید نشه

Happy_davood
چهارشنبه 20 آبان 1388, 16:01 عصر
بنده هم منظورم داخل حلقه بود . منظورم از اول یا آخر حلقه این بود که هر جایی که تونستید داخل حلقه بزارید . کافی بود یه بار امتحان کنید .

با توجه به شرحی که دادم (علت سفید شدن و ...) حدس زدنش آسون بود .

taeb1986
پنج شنبه 21 آبان 1388, 02:44 صبح
کنترل تایمر به طور داخلی multithredهست،چون راه حل ساده ای هستش اینو گفتم ضمنا قبلا من به این مشکل برخورد کردم،با تایمر حل شد

esmartiz_red
پنج شنبه 21 آبان 1388, 02:55 صبح
دوست عزیز شما باید از یک thread جداگانه استفاده کنی
backgroundworker هم که دوستمون گفتن در واقع همون threading هست که برای راحتی برنامه نویس ها به صورت کنترل ساخته شده
روش اصولی این کار اینه که شما پردازش اضافه کردن رکوردها توی بانک رو بندازی گردن به thread دیگه حالا با thread اصلی برنامه هم می تونی الباقی کاراتو انجام بدی الباقی روش ها می شه من درآوردی که تقریبا می شه گفت اصولی نیست شاید مشگل فعلی شمارو حل کنه اما معلوم نیست وقتی برنامه اجرایی بشه و یه event که شما در نظر نگرفتی اتفاق بیافته چه بلایی سر برنامه شما بیاد با روش من درآوردی

taeb1986
پنج شنبه 21 آبان 1388, 03:07 صبح
کاپیتان بلک جون شما از روش اصولی multithreading استفاده کن!بذار روش من در آوردی من واسه خودم بمونه.

captain_black81
پنج شنبه 21 آبان 1388, 17:22 عصر
از بحث های ن.بت شما هم داغتر شده

بچه ها ببخشیدا به کسی بر نخوره ولی اینجاییم که چیز یاد بگیریم دیگه
با تشکر از تائب و اسمارتیز و داوود و مدیر عزیز
من کار رو با thread و bcgrndwrkr دادم
مشکل progressbar حل شد
ولی label فقط اسم اولو نمایش میده و اسامی بعدیو نمیگیره

HAMRAHSOFT.IR
یک شنبه 12 دی 1389, 10:41 صبح
دوستان ميشه يك نمونه كوچي قرار بديد

ali.rezaei7
یک شنبه 12 دی 1389, 11:14 صبح
دوست عزیز ببین این دستور کارتو راه می ندازه.

this.refresh();
تغییرات صفحه رو بروز می کنه. ولی اگه بخوایید که صفحه قفل نشه باید از ترد استفاده کنی یا از دستور دواونت.

HAMRAHSOFT.IR
یک شنبه 12 دی 1389, 11:18 صبح
دوست عزیز ببین این دستور کارتو راه می ندازه.

this.refresh();
تغییرات صفحه رو بروز می کنه. ولی اگه بخوایید که صفحه قفل نشه باید از ترد استفاده کنی یا از دستور دواونت.

امكان داره يك نمونه ترد بزاريد ؟