مشاهده نسخه کامل
: جلوگیری از اجرای دستور click در هنگام doubleclick در notifyicon
shadmehrshadow1
26-07-2016, 18:06
سلام
من برای برنامه ام یک NotifyIcon قرار دادم که وقتی روی آیکون کلیک میشه یک فرم باز میشه و وقتی دابل کلیک میشه یک فرم دیگر.
فرمی هم که با تک کلیک باز میشه یکم سنگینه و دیر باز میشه برای همین وقتی من دابل کلیک می کنم و میخوام فرم دوم باز بشه اول فرم اول باز میشه سپس فرم دوم و این آزار دهنده است.
نمیشه کاری کرد که وقتی دابل کلیک می کنیم دیگه دستور کلیک اجرا نشه تا اون فرم اول که سنگین هست باز نشه؟
راه بهتری رو سراغ دارید ممنون میشم کمک کنید.
shadmehrshadow1
28-07-2016, 14:39
ممنون میشم از دوستان اگه کمک کنند یکیم گیر هستم و این داره کلافه ام می کنه
saeed_136915
28-07-2016, 16:33
سلام.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
shadmehrshadow1
29-07-2016, 16:05
سلام.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
سلام.
ممنون از وقتی که گذاشتید . اما این کد اصلا کار نکرد . البته اگرم کار می کرد فکر نکنم استفاده از تایمر زیاد روش جالبی باشه.
ممنون میشم اگه راه حل دیگه ای که کار کنه دارید کمک کنید.
saeed_136915
29-07-2016, 16:38
سلام.
کار کردنش که کار میکنه ولی باید event ها رو خودتون ست کنین و تایمر رو initialize بکنین...
راه حل دیگه ای فکر نکنم داشته باشه چون قبل از دابل کلیک اصولا کلیک هم فایر میشه...
szh_1367
29-07-2016, 21:46
سلام.
ممنون از وقتی که گذاشتید . اما این کد اصلا کار نکرد . البته اگرم کار می کرد فکر نکنم استفاده از تایمر زیاد روش جالبی باشه.
ممنون میشم اگه راه حل دیگه ای که کار کنه دارید کمک کنید.
اتفاقا تایمر ایده خوبی هست
راه حل دیگه : راست کلیک و چپ کلیک کردن فرم ها
shadmehrshadow1
31-07-2016, 15:25
سلام.
کار کردنش که کار میکنه ولی باید event ها رو خودتون ست کنین و تایمر رو initialize بکنین...
راه حل دیگه ای فکر نکنم داشته باشه چون قبل از دابل کلیک اصولا کلیک هم فایر میشه...
منونم
راستش منظورم این بود که این کد وقتی هنوز روی نوتیفی آیکون کلیکی نکردیم single کلیک رو یک بار در اجرای اول برنامه فراخوانی کرد. شاید به خاطر بالن یا منو برای کلیک راستش بوده که گذاشتم و اینکه براش فرقی بین کلیک راست و چپ نداره و در هر دو صورت اجرا میشه.
اتفاقا تایمر ایده خوبی هست
راه حل دیگه : راست کلیک و چپ کلیک کردن فرم ها
نمیدونم از نظر اینکه استفاده از تایمر روش خوبی مشکلی نیست ولی اینک تایمر توی برنامه زیاد بشه یکم غیر حرفه ای به نظر میاد که به خاطر یک کلیک بخواهیم برنامه رو در گیر تایمر کنیم و سرعت رو کمی پایین بیاره.
برای کلیک راست منو گذاشتم باز بشه نمیشه چپ و راستش کرد
szh_1367
01-08-2016, 00:01
منونم
راستش منظورم این بود که این کد وقتی هنوز روی نوتیفی آیکون کلیکی نکردیم single کلیک رو یک بار در اجرای اول برنامه فراخوانی کرد. شاید به خاطر بالن یا منو برای کلیک راستش بوده که گذاشتم و اینکه براش فرقی بین کلیک راست و چپ نداره و در هر دو صورت اجرا میشه.
نمیدونم از نظر اینکه استفاده از تایمر روش خوبی مشکلی نیست ولی اینک تایمر توی برنامه زیاد بشه یکم غیر حرفه ای به نظر میاد که به خاطر یک کلیک بخواهیم برنامه رو در گیر تایمر کنیم و سرعت رو کمی پایین بیاره.
برای کلیک راست منو گذاشتم باز بشه نمیشه چپ و راستش کرد
من اطلاعات دقیقی از برنامه ات ندارم که بخواهم ایده ای بهت بدهم مثل اینکه دارم تو تاریکی تیراندازی میکنم
میتونی هر دو فرم رو در یک تب پیج قرار بدی با تاخیری که در اجرای صفحه ایجاد میشه نرم افزار یکی از تب پیج ها رو غیر فعال کنه
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
shadmehrshadow1
01-08-2016, 21:14
من اطلاعات دقیقی از برنامه ات ندارم که بخواهم ایده ای بهت بدهم مثل اینکه دارم تو تاریکی تیراندازی میکنم
میتونی هر دو فرم رو در یک تب پیج قرار بدی با تاخیری که در اجرای صفحه ایجاد میشه نرم افزار یکی از تب پیج ها رو غیر فعال کنه
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
راستش برنامه من یه آیکون در نوار استارت کنار ساعت داره (notifyicon) که وقتی روی آیکون کلیک راست می کنم یک منو باز میشه . و وقتی روی آیکون تک کلیک(چپ) می کنم فرم ۱ باز میشه و وقتی دابل کلیک می کنم فرم ۲ باز میشه.
مشکل اینجاست که فرم اول من توش کنترل زیاد داره و حجم دستورایی هم که توش اجرا و انجام میشه زیاده برای همین موقع باز شدنش کمی تاخیر ایجاد میشه و زمان میبره.
حالا وقتی روی آیکون دابل کلیک کنم وقتی میخواد فرم ۲ اجرا بشه اول دستور تک کلیک که همون اجرای فرم ۱ (فرم سنگین) هست اجرا میشه و همین باعث میشه که فرم ۲ که فرم سبکی هست با تاخیر اجرا بشه که این موضوع آزار دهنده است.
به نظر شما استفاده از نخ (threadin) البته اگه درست نوشته باشم روش مناسبیه؟ البته من تا حالا باهاش کار نکردم نمیدونم چجوریه ولی به نظرتون میشه از طریق thread کاری کرد که هردو دستور با هم اجرا بشه همزمان, که اون تاخیر ایجاد نشه؟ و مجبور نباشیم که صبر کنیم تا دستورات کلیک ابتدا به صورت کامل اجرا بشه(اجرا شدن فرم ۱ ) و سپس دستورات دابل کلکیک (اجرا شدن فرم ۲ ) .
راستش برنامه من یه آیکون در نوار استارت کنار ساعت داره (notifyicon) که وقتی روی آیکون کلیک راست می کنم یک منو باز میشه . و وقتی روی آیکون تک کلیک(چپ) می کنم فرم ۱ باز میشه و وقتی دابل کلیک می کنم فرم ۲ باز میشه.
مشکل اینجاست که فرم اول من توش کنترل زیاد داره و حجم دستورایی هم که توش اجرا و انجام میشه زیاده برای همین موقع باز شدنش کمی تاخیر ایجاد میشه و زمان میبره.
حالا وقتی روی آیکون دابل کلیک کنم وقتی میخواد فرم ۲ اجرا بشه اول دستور تک کلیک که همون اجرای فرم ۱ (فرم سنگین) هست اجرا میشه و همین باعث میشه که فرم ۲ که فرم سبکی هست با تاخیر اجرا بشه که این موضوع آزار دهنده است.
به نظر شما استفاده از نخ (threadin) البته اگه درست نوشته باشم روش مناسبیه؟ البته من تا حالا باهاش کار نکردم نمیدونم چجوریه ولی به نظرتون میشه از طریق thread کاری کرد که هردو دستور با هم اجرا بشه همزمان, که اون تاخیر ایجاد نشه؟ و مجبور نباشیم که صبر کنیم تا دستورات کلیک ابتدا به صورت کامل اجرا بشه(اجرا شدن فرم ۱ ) و سپس دستورات دابل کلکیک (اجرا شدن فرم ۲ ) .
سلام.
بله شما باید از Task یا Thread استفاده کنید و رویداد کلیک رو با تاخیر اجرا کنید مثلاً توی 1 ثانیه چک کنید اگر دابل کیک شد رویداد کلیک دیگه کنسل میشه و اگر توی یک ثانیه دابل کلیک نشد رویداد کلیک رو اجرا کنید.
هیچ راه دیگه ای به ذهنم نمیرسه چون رویداد کلیک همیشه زودتر از دابل کلیک اجرا میشه.
szh_1367
02-08-2016, 13:17
راستش برنامه من یه آیکون در نوار استارت کنار ساعت داره (notifyicon) که وقتی روی آیکون کلیک راست می کنم یک منو باز میشه . و وقتی روی آیکون تک کلیک(چپ) می کنم فرم ۱ باز میشه و وقتی دابل کلیک می کنم فرم ۲ باز میشه.
مشکل اینجاست که فرم اول من توش کنترل زیاد داره و حجم دستورایی هم که توش اجرا و انجام میشه زیاده برای همین موقع باز شدنش کمی تاخیر ایجاد میشه و زمان میبره.
حالا وقتی روی آیکون دابل کلیک کنم وقتی میخواد فرم ۲ اجرا بشه اول دستور تک کلیک که همون اجرای فرم ۱ (فرم سنگین) هست اجرا میشه و همین باعث میشه که فرم ۲ که فرم سبکی هست با تاخیر اجرا بشه که این موضوع آزار دهنده است.
به نظر شما استفاده از نخ (threadin) البته اگه درست نوشته باشم روش مناسبیه؟ البته من تا حالا باهاش کار نکردم نمیدونم چجوریه ولی به نظرتون میشه از طریق thread کاری کرد که هردو دستور با هم اجرا بشه همزمان, که اون تاخیر ایجاد نشه؟ و مجبور نباشیم که صبر کنیم تا دستورات کلیک ابتدا به صورت کامل اجرا بشه(اجرا شدن فرم ۱ ) و سپس دستورات دابل کلکیک (اجرا شدن فرم ۲ ) .
بله شما برای حرفه ای بدون برنامه راهی جز استفاده از نخ ندارید (حداقلش اینکه به ذهن من نمیرسه ) . با اقا علی موافقم
در اصل نخ تاخیر ایجاد میکنه همانند تایمر به شما زمان میدهد که کلیک یا دبل کلیک بودن رو تشخیص بدهید البته استفاده از نخ خیلی اصولی تر و حرفه ای تر هست
shadmehrshadow1
02-08-2016, 16:25
سلام.
بله شما باید از Task یا Thread استفاده کنید و رویداد کلیک رو با تاخیر اجرا کنید مثلاً توی 1 ثانیه چک کنید اگر دابل کیک شد رویداد کلیک دیگه کنسل میشه و اگر توی یک ثانیه دابل کلیک نشد رویداد کلیک رو اجرا کنید.
هیچ راه دیگه ای به ذهنم نمیرسه چون رویداد کلیک همیشه زودتر از دابل کلیک اجرا میشه.
بله شما برای حرفه ای بدون برنامه راهی جز استفاده از نخ ندارید (حداقلش اینکه به ذهن من نمیرسه ) . با اقا علی موافقم
در اصل نخ تاخیر ایجاد میکنه همانند تایمر به شما زمان میدهد که کلیک یا دبل کلیک بودن رو تشخیص بدهید البته استفاده از نخ خیلی اصولی تر و حرفه ای تر هست
راستش من تا حالا از نخ استفاده نکردم نمیدونم چه جوری کار می کنه. کدی چیزی دارید که بتونم ازش استفاده کنم ؟ یا بفهمم چه طور باید از نخ استفاده کنم.
راستش من تا حالا از نخ استفاده نکردم نمیدونم چه جوری کار می کنه. کدی چیزی دارید که بتونم ازش استفاده کنم ؟ یا بفهمم چه طور باید از نخ استفاده کنم.
تستش نکردم امیدوارم خودت بقیه اش رو بری:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
ضمن احترام و گران قدر دانستن نظر تمامی دوستان، بهتر از برخی ابهام ها در تاپیک رو این طوری توضیح دهم:
به نظر میاد که به خاطر یک کلیک بخواهیم برنامه رو در گیر تایمر کنیم و سرعت رو کمی پایین بیاره.
تایمر ها سرعت برنامه را کم نمی کنند، بلکه Thread اصلی که به فرم یا object جاری اختصاص داده شده است را زمان بند می کنند. در صورتی هم که Thread جاری کاملا درگیر باشد، به علت event محور بودن، فایر نمی شوند. در صورتیکه تعداد زمان بند ها در یک Thread افزایش یابد، حالتی شبیه round robin به وجود می آید( آن چیزی که در OS باعث می شود فکر کنیم همه ی کار ها با هم انجام می شود.) به وجود آوردن چنین حالتی در Thread اصلا کار اصولی نیست. در این حالت است که جمله ی بیان شده مبنی بر کند کردن توسط تایمر پر رنگ می شود، کند خیر، ناهمگون می شود! چون مدت زمان اجرای Timer ها کلا وابسته به هم می شود.
اینک تایمر توی برنامه زیاد بشه یکم غیر حرفه ای
دقیقا. به همین علت است. در ضمن مگر قبلا چند تایمر داشته اید که یک تایمر برنامه ی شما را در این حالت ببرد؟
در اصل نخ تاخیر ایجاد میکنه همانند تایمر به شما زمان میدهد که کلیک یا دبل کلیک بودن رو تشخیص بدهید البته استفاده از نخ خیلی اصولی تر و حرفه ای تر هست
ضمن اینکه این جمله ممکن است در اینجا صحیح باشد، این جمله در همه جا صحیح نیست. هر کدام جهت کاری مناسب هستند. همان طور که در بالا بیان شد، تایمر زمان بند است و Thread ها مجموعه دستورات اجرایی به صورت موازی. از نظر تعریفی این دو با هم وجه تشابهی ندارند و در توضیح تکمیلی می توان گفت که Thread می تواند زمان بندی شود و مانند تایمر کار کند(مانند مثال علی آقا)
سوال اصلی) آیا Thread دیگری را زمان بند کنیم بهتر است یا Thread جاری را Time Slice کنیم؟
اگر قرار است وظیفه ای طولانی را در زمان بند های خود اجرا کنیم، طوری که درگیری کد طوری باشد که زمان بندی بخش های دیگر را تحت تاثیر قرار دهد، قطعا روش زمان بندی Thread بهتر از Timer است. در غیر این صورت روش Timer بهتر است. چرا؟
1- ایجاد هر Thread و حذف آن یک بار پردازشی بر روی OS دارد.
2- به ازای هر Thread که ایجاد می شود یک Stack Watermark ایجاد می شود.
3- به ازای هر Thread که ایجاد می شود ده ها پراپرتی می بایست sync شوند.
4- در صورت نیاز، دسترسی Thread ها به حافظه ی private هر Thread دیگر باید توسط invoke انجام شود.
و ...
تمامی این موارد از نظر بهینه بودن حافظه و پردازش خود یک سوال ایجاد می کند. و در این جا دیگر نمی توان گفت استفاده از Thread حرفه ای تر است!
با توجه به مطالب بیان شده، آیا برای نمایش یک فرم نیاز است تا Thread ایجاد شود؟
این سوال دو پاسخ دارد:
1- اگر فرم طوری نمایش داده شود و رفتار Modal (غیر فعال شدن فرم جاری(parent) و فعال شدن فرم جدید مد نظر) داشته باشد، آنگاه Thread الزامی است.
2- اگر فرم باز شونده رفتار Modal نداشته باشد، آنگاه با توجه به بار پردازشی کم، به Thread جدیدی نیاز نیست.
bool singleClick = false;
این خط احتمال خطا دارد. متغیر عمومی که بدین صورت تعریف شود نمی تواند Thread Safe باشد. می بایست متغیر volatile نیز باشد.
ThreadSafe: دسترسی همزمان به یک نباید باعث خطا در خواندن و نوشتن و یا تاخیر در آن شود.
مثال با تایمر این عمل را روی وین فرم، در اینجا ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])می توانید دریافت کنید. (کد نوشته شده بسیار کثیف است، حال نداشتم:n02::n02::n02:)
موفق باشید.
این خط احتمال خطا دارد. متغیر عمومی که بدین صورت تعریف شود نمی تواند Thread Safe باشد. می بایست متغیر volatile نیز باشد.
در کد نوشته شده، هیچ احتمال خطایی وجود نداره، میتونید توضیح بدید چطوری ممکنه نرم افزار به خطا بخوره وقتی متغیر singleClick در ترد اصلی وقتی روی دکمه کلیک میشه مقدارش تغییر میکنه و در کلیک های بعدی به هیچ عنوان عمل نمی کنه مگر اینکه تسک ساخته شده به پایان برسه و مقدار رو مجدد false کنه؟ این متغیر به هیچ عنوان نمیتونه به طور همزمان در دو ترد مقدار دهی بشه که شما اصرار بر volatile تعریف شدنش دارید.
چطوری محاسبه کردید که احتمال خطا وجود داره؟ دوس دارم بدونم، تشکر.
از نظر خودم فقط در صورتی این متغیر دیگه مقدار دهی نمیشه که خط اجرایی تسک به انتها نرسه، که این به volatile مربوط نمیشه!
علی آقا شما از استادان بنده هستید که خیلی قبولشان دارم.:n16: اگر جسارتی کردم، ببخشید.:n37:
مقدار دهی بشه که شما اصرار بر volatile تعریف شدنش دارید.
بنده غلط بکنم اصراری داشته باشم. اما شرح ما وقع این است:
همان طور که در بالا بیان شد، Thread Safe همیشه به معنای دو write همزمان نیست. این واژه در سه حالت معنا می دهد:
1- نوشتن - نوشتن
2- نوشتن - خواندن
3- خواندن - نوشتن
فرض شما در حالت اول صحیح است. اما اگر در زمان نوشتن false در task، عمل رویداد جهت خواندن فراهم شود، آنگاه چه می شود؟ رویداد کنسل می شود در صورتی که کار اصلی در task به اتمام رسیده است. دراینجا فوق فوقش کاربر مجبور است یک بار دیگر کلیک کند! می توان این را به گونه ای خطا دانست. برای همین دلیلی بر اصرار تا اینجا و در اینجا نیست.:n16:
اما اگر event توسط ماشین زده شود مانند اتمام یک عمل Async یا دریافت اطلاعات و ... ، آنگاه ماشین دوبار رویداد نمی فرستد. برای همین به صورت یک رفتار امن ترجیح می دهم چنین متغیر هایی volatile تعریف شوند حتی در این مثال.
حال مسئله را کمی ریز تر کنیم (البته ذکر این مورد در فرض تاپیک خود را نشان نمی دهد جلو تر علت بیان می شود...)، فرض کنید هر دو Thread در یک core از پردازنده انجام شود. با فرض اینکه پردازنده Hyper Thread ندارد، و پردازنده در حال اجرای دستور تغییر متغیر در task است و در این میان OS، سوییچ کرده و عمل read در thread دیگر را انجام می دهد. توضیح: در یک پردازنده ی 32 بیتی، اکثر اعمال 64بیتی، نمی تواند در یک کلاک انجام شود. این یعنی اگر دو کلاک لازم باشد کار انجام شود و یک کار آن انجام شده باشد و کار دوم آن مانده باشد و در این حالت OS سراغ فرمان دیگری جهت خواندن رفته باشد آنگاه اطلاعات اشتباه خوانده می شود در یک توضیح عددی:
پردازنده باید عدد 64 بیتی 0xff00ff00ff00ff00 را درون حافظه بریزد و در حالی که فقط در هر کلاک 32 بیت آن را می تواند بریزد و در این هنگام عمل سوییچ انجام شود، Thread دیگر به جای خواندن این عدد، به اشتباه 0xff00ff0000000000 را می خواند. چون هنوز بخش دوم در حافظه کپی نشده است. حال volatile کردن برای کامپایلر این توضیح را به عمل می آورد که باید رفتاری کامل انجام شود و سپس read صورت گیرد اما این باز هم پایان کار نیست.(مبحث lock، خارج از بجث است.) در صورتی هم ممکن است که عمل انجام شده باشد یعنی هر دو انتقال؛ ولی هنوز مقادیر در کش به روز رسانی نشده باشند آنگاه یک عمل update نیاز است تا وضعیت کش بهبود پیدا کند.(volatile در این مسیر پررنگ تر است.) گاهی چندین سرکشی ممکن است به یک متغیر معمولی انجام شود تا مقدار واقعی آن از کش خوانده شود. یعنی در موضوع تاپیک، ممکن است چندین کلیک کاربر از بین رود، خصوصا زمانی که حجم مصرفی رم بالا و پردازنده دارای usage باشد.(هر چند که فقط یک احتمال است و کاربر بسیار بسیار کندتر از ماشین و احتمال قابل صرفه نظر ولی موجود، قانون مورفی!!!جهت خنده مطالعه ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]قانون-جالب-مورفی-از-کجا-آمد-لیستی-از-این-قوانین)کنید، بخش مهندسیش فقط درسته که مربوط به ماشین آلاته بقیش مربوط به بحث مانیست)
در بالا بیان شد که مثال 64 بیت در شرح تاپیک دیده نمی شود، چرا؟ چون متغیر bool یک متغیر atomic است. متغیر atomic متغیری است که تنها یک دستور برای اجرا نیاز دارد و هیچگاه حالت چند دستوری به خود نمی گیرد. لذا مقدار غلط در آن وجود ندارد و فقط شرط به روز رسانی در کش ملاک است.
کوچیکتیم علی آقا.
موفق باشید.
فراموش شد:
متغیر های Atomic، منبع ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ](v=vs.71).aspx)
علی آقا شما از استادان بنده هستید که خیلی قبولشان دارم.:n16: اگر جسارتی کردم، ببخشید.:n37:
بنده غلط بکنم اصراری داشته باشم. اما شرح ما وقع این است:
همان طور که در بالا بیان شد، Thread Safe همیشه به معنای دو write همزمان نیست. این واژه در سه حالت معنا می دهد:
1- نوشتن - نوشتن
2- نوشتن - خواندن
3- خواندن - نوشتن
فرض شما در حالت اول صحیح است. اما اگر در زمان نوشتن false در task، عمل رویداد جهت خواندن فراهم شود، آنگاه چه می شود؟ رویداد کنسل می شود در صورتی که کار اصلی در task به اتمام رسیده است. دراینجا فوق فوقش کاربر مجبور است یک بار دیگر کلیک کند! می توان این را به گونه ای خطا دانست. برای همین دلیلی بر اصرار تا اینجا و در اینجا نیست.:n16:
......
خیلی ممنون از توضیحاتتون راضی به زحمت نیستم اما شاید متوجه سوال من نشدید.
من پرسیدم در چه زمانی "کد نوشته شده" به خطا خواهد خورد یا احتمال خطا خواهد داشت؟ برداشت من از خطا در کد بالا در واقع همون باگ هست نه چیز دیگه، شما دارید مثال هایی میزنید که "غیر" از کد نوشته شده هست و این در حالی هست که بنده خودم به این امر واقف هستم، بله در صدتا مثال دیگه ممکنه به خطا بخوره! چه در سیستم 64 بیتی و چه در سیستم 32 بیتی یا هر سیستم و سیستم عامل دیگری متغیر singleClick به طور همزمان در "دو ترد" فراخوانی نخواهد شد (write)،کد نوشته شده در واقع مثال شما رو توجیه نمیکنه چون کاربر بعد از یکبار کلیک میتونه 100 باز دیگه هم کلیک کنه. و کدی نوشته نشده که دکمه ی کلیک رو غیر فعال کنه و در واقع اتفاقی نیوفته، بنابراین اگر در دو ترد بالا همزمان مقدار singleClick خونده بشه، باز هم همون اتفاقی خواهد افتاد که توی صدبار کلیک دیگر افتاده و مقدار false برگردونده شده و تسک کلیک اجرا نخواهد شد. به طور ساده تر در کد مورد نظر متغیر singleClick فقط باید وقتی اجرا بشه که کار تسک به اتمام رسیده باشه و به قول شما اگر در هنگام write شرط read در رویداد کلیک فراخونی بشه باز هم مقدار false یا true خواهد بود و همون اتفاقی خواهد افتاد که در تعریف متغیر در حالت volatile رخ خواهد داد... وقتی میگیم خطایی رخ داده یا احتمال خطا وجود داره که در دریافت متغیر به exception برخورد کنیم یا عملکرد الگوریتم به درستی عمل نکنه.شما اگر الگوریتم کد نوشته شده رو رسم کنید میبینید که هیچ احتمال خطایی وجود نداره، در هر حال ممنون از توضیحاتتون.
موفق باشید.
szh_1367
06-08-2016, 14:00
ضمن احترام و گران قدر دانستن نظر تمامی دوستان، بهتر از برخی ابهام ها در تاپیک رو این طوری توضیح دهم:
تایمر ها سرعت برنامه را کم نمی کنند، بلکه Thread اصلی که به فرم یا object جاری اختصاص داده شده است را زمان بند می کنند. در صورتی هم که Thread جاری کاملا درگیر باشد، به علت event محور بودن، فایر نمی شوند. در صورتیکه تعداد زمان بند ها در یک Thread افزایش یابد، حالتی شبیه round robin به وجود می آید( آن چیزی که در OS باعث می شود فکر کنیم همه ی کار ها با هم انجام می شود.) به وجود آوردن چنین حالتی در Thread اصلا کار اصولی نیست. در این حالت است که جمله ی بیان شده مبنی بر کند کردن توسط تایمر پر رنگ می شود، کند خیر، ناهمگون می شود! چون مدت زمان اجرای Timer ها کلا وابسته به هم می شود.
دقیقا. به همین علت است. در ضمن مگر قبلا چند تایمر داشته اید که یک تایمر برنامه ی شما را در این حالت ببرد؟
ضمن اینکه این جمله ممکن است در اینجا صحیح باشد، این جمله در همه جا صحیح نیست. هر کدام جهت کاری مناسب هستند. همان طور که در بالا بیان شد، تایمر زمان بند است و Thread ها مجموعه دستورات اجرایی به صورت موازی. از نظر تعریفی این دو با هم وجه تشابهی ندارند و در توضیح تکمیلی می توان گفت که Thread می تواند زمان بندی شود و مانند تایمر کار کند(مانند مثال علی آقا)
سوال اصلی) آیا Thread دیگری را زمان بند کنیم بهتر است یا Thread جاری را Time Slice کنیم؟
اگر قرار است وظیفه ای طولانی را در زمان بند های خود اجرا کنیم، طوری که درگیری کد طوری باشد که زمان بندی بخش های دیگر را تحت تاثیر قرار دهد، قطعا روش زمان بندی Thread بهتر از Timer است. در غیر این صورت روش Timer بهتر است. چرا؟
1- ایجاد هر Thread و حذف آن یک بار پردازشی بر روی OS دارد.
2- به ازای هر Thread که ایجاد می شود یک Stack Watermark ایجاد می شود.
3- به ازای هر Thread که ایجاد می شود ده ها پراپرتی می بایست sync شوند.
4- در صورت نیاز، دسترسی Thread ها به حافظه ی private هر Thread دیگر باید توسط invoke انجام شود.
و ...
تمامی این موارد از نظر بهینه بودن حافظه و پردازش خود یک سوال ایجاد می کند. و در این جا دیگر نمی توان گفت استفاده از Thread حرفه ای تر است!
با توجه به مطالب بیان شده، آیا برای نمایش یک فرم نیاز است تا Thread ایجاد شود؟
این سوال دو پاسخ دارد:
1- اگر فرم طوری نمایش داده شود و رفتار Modal (غیر فعال شدن فرم جاری(parent) و فعال شدن فرم جدید مد نظر) داشته باشد، آنگاه Thread الزامی است.
2- اگر فرم باز شونده رفتار Modal نداشته باشد، آنگاه با توجه به بار پردازشی کم، به Thread جدیدی نیاز نیست.
این خط احتمال خطا دارد. متغیر عمومی که بدین صورت تعریف شود نمی تواند Thread Safe باشد. می بایست متغیر volatile نیز باشد.
ThreadSafe: دسترسی همزمان به یک نباید باعث خطا در خواندن و نوشتن و یا تاخیر در آن شود.
مثال با تایمر این عمل را روی وین فرم، در اینجا ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])می توانید دریافت کنید. (کد نوشته شده بسیار کثیف است، حال نداشتم:n02::n02::n02:)
موفق باشید.
زیاد سخت نگیر قرار نیست برنامه ساخت فضاپیما به کره مریخ رو بنویسیم
استفاده از thread همانند استفاده از چاقو هست اگر درست ازش استفاده کنید بسیار کارامد خواهد بود در غیر این صورت ابزاری خطرناک خواهد بود
درصورتی که شما به درستی از thread استفاده کنید قطعا ابزاری حرفه ای تر از تایمر خواهد بود
shadmehrshadow1
06-08-2016, 17:30
خیلی ممنون از دوستان عزیز که وقت گذاشتن و استفاده کردیم از توضیحاتشون.
مثال با تایمر این عمل را روی وین فرم، در اینجا می توانید دریافت کنید. (کد نوشته شده بسیار کثیف است، حال نداشتم)
موفق باشید.
در کد نوشته شده، هیچ احتمال خطایی وجود نداره، میتونید توضیح بدید چطوری ممکنه نرم افزار به خطا بخوره وقتی متغیر singleClick در ترد اصلی وقتی روی دکمه کلیک میشه مقدارش تغییر میکنه و در کلیک های بعدی به هیچ عنوان عمل نمی کنه مگر اینکه تسک ساخته شده به پایان برسه و مقدار رو مجدد false کنه؟ این متغیر به هیچ عنوان نمیتونه به طور همزمان در دو ترد مقدار دهی بشه که شما اصرار بر volatile تعریف شدنش دارید.
ممنونم .اما دوستمون درست میگن سورسی که شما گذاشتید از دستور تک کلیک فقط یک بار میشه استفاده کرد و اگه بخوایم مجددا دوباره دستور تک کلیک رو اجرا کنیم دیگه کار نمیکنه.
تستش نکردم امیدوارم خودت بقیه اش رو بری:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
من از وی بی دات نت استفاده می کنم . تبدیلش کردم به وی بی حالا نمیدونم شاید بد تبدیلش کردم ولی خیلی بد کار می کرد این کد، به صورتی که هی فرم یک باز میشه و بسته میشه. توی حالت عادی بدون استفاده از نخ و تایمر این اتفاق کمتر میفته.
______________
نمدونم والا ، فرم 1 که سنگین هست. تعداد کنترل هاش زیاده و کمی باعث میشه لود شدن فرم طول بکشه . البته یه چندتا حلقه هم توشه.
با عرض پوزش یه سوال دیگه ، میشه لود شدن کنترل های فرم رو در هنگام اجرا کنترل کرد؟ یا حد اقلش شاید یه پروگرس بار برای اجرای فرم بزارم بزارم که هنگام لود شدن کنترل ها نمایش داده بشه؟ مثل backgroundworker . معمولا واسه اجرای کد میشه استفاده کرد اما برای لود شدن فرم رو نمیدونم.
درصورتی که شما به درستی از thread استفاده کنید قطعا ابزاری حرفه ای تر از تایمر خواهد بود
ای خدا خیرت بده، قطعا موافقم و من هم همین رو گفتم.:n02: هر چیز جای خودش، نه فقط من بلکه اگه همه استفاده کنیم.:n16:
وقتی میگیم خطایی رخ داده یا احتمال خطا وجود داره که در دریافت متغیر به exception برخورد کنیم یا عملکرد الگوریتم به درستی عمل نکنه.
دقیقا صحیح است استاد (استاد به معنی واقعی سو تفاهم نشود.). اما بخش دوم هم هست وقتی احتمال دارد یک کلیک شما از بین برود یعنی الگوریتم صحیح نبوده، نه باز هم این پاسخ نیست و الگوریتم صحیح است، بستر صحیح نبوده. کلمه ی volatile از اصلاح کننده های بستر است. متاسفانه خطاهای نوع دوم و سوم در Thread Safe دارای exception نیستند.
در ضمن نمی دانستم که بیان گذاشتن یک کلمه ی volatile نیازمند چنین تعاریف طولانی هست.
میشه لود شدن کنترل های فرم رو در هنگام اجرا کنترل کرد؟ یا حد اقلش شاید یه پروگرس بار برای اجرای فرم بزارم بزارم که هنگام لود شدن کنترل ها نمایش داده بشه؟ مثل backgroundworker . معمولا واسه اجرای کد میشه استفاده کرد اما برای لود شدن فرم رو نمیدونم.
بین دو Event، با نام های Load و Shown را امتحان کنید. همچنین contstructor فرم نیز هست که عناصر ساخته و چیده می شوند اما اجرای این بخش در new شدن فرم است نه show. آن را نیز بررسی کنید ببینید به کارتان می آید. در ضمن پیشنهاد می کنم برای loading از یک فرم دیگر استفاده کنید و وضعیت را به آن ارسال کنید. همچنین می توانید از روش ترکیبی به سلیقه ی خودتان از موارد بیان شده نیز استفاده کنید.
در ضمن راهی برای سبک شدن فرمتان نیست؟ بگویید شاید با دوستان بتوانیم پیشنهاد فرم سبک تر بدهیم.
موفق باشید.
من از وی بی دات نت استفاده می کنم . تبدیلش کردم به وی بی حالا نمیدونم شاید بد تبدیلش کردم ولی خیلی بد کار می کرد این کد، به صورتی که هی فرم یک باز میشه و بسته میشه. توی حالت عادی بدون استفاده از نخ و تایمر این اتفاق کمتر میفته.
انتظار هر نوع خطایی رو داشتم ولی نه اینکه فرم اول باز بشه ومجدد بسته بشه :n04:. من اصلاً کد باز شدن و بسته شدن فرم رو توی کدهام ننوشتم.ولی احتمال میدم:
1.شما کدهای نمایش فرم رو توی دستورات Dispatcher اجرا نکرده باشید.
2.جای دیگه تایمری یا چیزی برای مخفی کردن فرم نوشتید.
دستورات رو در Try و Catch هندل کنید امیدوارم که به خطا نخورده باشید.
زیاد سخت نگیر قرار نیست برنامه ساخت فضاپیما به کره مریخ رو بنویسیم
استفاده از thread همانند استفاده از چاقو هست اگر درست ازش استفاده کنید بسیار کارامد خواهد بود در غیر این صورت ابزاری خطرناک خواهد بود
درصورتی که شما به درستی از thread استفاده کنید قطعا ابزاری حرفه ای تر از تایمر خواهد بود
توی ارسال و دریافت اطلاعات به سرور و کلاینت لو لول ترینی که ما میتونیم ازش استفاده کنیم برنامه نویسی سوکت هست حداقل به نظر میاد توی دات نت اینطوری هست.
تایمر و Task و async await ... همشون از Thread استفاده می کنن در واقع برای راحتی کار برنامه نویس نوشته شدن که لول پایینش همون Thread هست.
مثلاً شما اگر صدتا Task رو توی فکتوری new کنید و اجرا کنید خیلی کند تر از صد تا Thread اجرا خواهد شد که خاصیت isbackgournd اش false باشه.علتش اینه که ترد های تعریف شده در Task ها قابلیت isbackground و تنظیمات مدیریت شده ای دارن.
نوشتن برنامه های مالتی تردینگ در ابتدای امر کار سختی نیست ولی اگر بدرستی manage نشه حتی ممکنه یک پروژه رو fail کنه.
shadmehrshadow1
07-08-2016, 21:20
در ضمن راهی برای سبک شدن فرمتان نیست؟ بگویید شاید با دوستان بتوانیم پیشنهاد فرم سبک تر بدهیم.
موفق باشید.
راستش یه تقویم هستش که ماهانه هست. توش 42 تا کنترل واسه نمایش عدد روز ، روزهای شمسی هست. و42 تا واسه قمری و 42 تا برای میلادی. نمیدونم آیا راه بهتری هست یا نه.
بله دقیقا میخواهم برای لودینگ از یه فرم دیگه استفاده کنم اما راه درستش رو برای قرار دادن لودینگ به منظور لود شدن کنترل ها رو بلد نیستم. فکر کنم از backgroundwoker باید استفاده بشه.
انتظار هر نوع خطایی رو داشتم ولی نه اینکه فرم اول باز بشه ومجدد بسته بشه . من اصلاً کد باز شدن و بسته شدن فرم رو توی کدهام ننوشتم.ولی احتمال میدم:
1.شما کدهای نمایش فرم رو توی دستورات Dispatcher اجرا نکرده باشید.
2.جای دیگه تایمری یا چیزی برای مخفی کردن فرم نوشتید.
دستورات رو در Try و Catch هندل کنید امیدوارم که به خطا نخورده باشید.
راستش کد یه جوری برایم نامفهوم بود تبدیل کردنش به Vb.net برای یکم سخت بود مخصوصا که نتوستم اصلا از دستور Dispatcher استفاده کنم . مثل اینکه کار کردنش توی وی بی دات نت متفاوت هست و دستورات متفاوتی داره.
راستش کد یه جوری برایم نامفهوم بود تبدیل کردنش به Vb.net برای یکم سخت بود مخصوصا که نتوستم اصلا از دستور Dispatcher استفاده کنم . مثل اینکه کار کردنش توی وی بی دات نت متفاوت هست و دستورات متفاوتی داره.
اگر شما از WPF استفاده میکنید:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر شما از ویندوز فرم استفاده میکنید به جای Dispatcher.Invoke از Invoke به تنهایی استفاده کنید به جای Dispatcher.Invoke.
این قسمت کد مهمه و اگر نذارید نرم افزارتون با خطای دسترسی ترد ها مواجه میشه.
shadmehrshadow1
08-08-2016, 20:46
اگر شما از WPF استفاده میکنید:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر شما از ویندوز فرم استفاده میکنید به جای Dispatcher.Invoke از Invoke به تنهایی استفاده کنید به جای Dispatcher.Invoke.
این قسمت کد مهمه و اگر نذارید نرم افزارتون با خطای دسترسی ترد ها مواجه میشه.
خیلی ممنون . درست شد.
فقط من به جای Task از Thread استفاده کردم چون دستور Task چیزی به عنوان Start نداشت . حالا نمی دونم کار درستی کردم یا نه. کد رو به این صورت تغییر دادم.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
سلام
تاپیک عنوان ساده داشت وندیده بودم... عجب بحث داغی ایجاد شده :n02:
البته تمام پست های دوستان را نخواندم :n40: الآن ساعت 0215 بامداد است و دارم p30world میخوانم
اگر بخواهم یک راه ساده ومطمئن را استفاده کنم و مدام هم به تداخل ریسمان و چند کلیک و... فکر نکنم احتمالا در نگاه اول کد زیر را خواهم نوشت ...
نگه داری یک عدد int به عنوان نسخه در پاره ای موارد مشابه کمک زیادی میکند، خود مایکروسافت هم در بخشی از کدهای داخلی Enumerable ها و مقابله با مشکلات چند ریسمانی از کدهای مشابه مفهوم version استفاده کرد. بطور معمول به عنوان بخشی از یک جور راه حل روتین قابل اعمال است و زیاد نیاز به فکر کردن به جنبه های مختلف ندارد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
(زیاد هم نگران پرشدن int نباشید، اگر کاربر شما هر ثانیه یک کلیک کند و این کار را پیوسته بدون خواب وخوراک در 24 ساعت روز و 7 روز هفته و... ادامه دهد، 60 سال طول میکشد! برای ساعتی 100 کلیک مداوم 2000 سال و در عمل وبا اعداد واقعی چند هزار سالی طول میکشد!)
برای WPF همانطور که در کد دوستان بود بجای BeginInvoke باید از Dispatcher استفاده شود.
در خصوص volatile هم در مورد دسترسی به متغییر های ساده ای که مقدار مستقیم توسط ریسمان های متفاوت امکان تغییر دارد، بهتر است استفاده شود، مثال های ساده ای میتوان بیان کرد که استفاده وعدم استفاده تفاوت کاملا مشهود دارد ولی در نهایت تصمیم شرایط و محل واستفاده به عهده برنامه نویس ودر تخصص او است، به عنوان نمونه در کد فوق نباید استفاده شود و استفاده از کلاس Interlocked بسیار مناسب ومطمئن تر عمل میکند.
شب خوش.
:n11:
shadmehrshadow1
09-08-2016, 15:00
سلام
تاپیک عنوان ساده داشت وندیده بودم... عجب بحث داغی ایجاد شده :n02:
البته تمام پست های دوستان را نخواندم :n40: الآن ساعت 0215 بامداد است و دارم p30world میخوانم
اگر بخواهم یک راه ساده ومطمئن را استفاده کنم و مدام هم به تداخل ریسمان و چند کلیک و... فکر نکنم احتمالا در نگاه اول کد زیر را خواهم نوشت ...
نگه داری یک عدد int به عنوان نسخه در پاره ای موارد مشابه کمک زیادی میکند، خود مایکروسافت هم در بخشی از کدهای داخلی Enumerable ها و مقابله با مشکلات چند ریسمانی از کدهای مشابه مفهوم version استفاده کرد. بطور معمول به عنوان بخشی از یک جور راه حل روتین قابل اعمال است و زیاد نیاز به فکر کردن به جنبه های مختلف ندارد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
(زیاد هم نگران پرشدن int نباشید، اگر کاربر شما هر ثانیه یک کلیک کند و این کار را پیوسته بدون خواب وخوراک در 24 ساعت روز و 7 روز هفته و... ادامه دهد، 60 سال طول میکشد! برای ساعتی 100 کلیک مداوم 2000 سال و در عمل وبا اعداد واقعی چند هزار سالی طول میکشد!)
برای WPF همانطور که در کد دوستان بود بجای BeginInvoke باید از Dispatcher استفاده شود.
در خصوص volatile هم در مورد دسترسی به متغییر های ساده ای که مقدار مستقیم توسط ریسمان های متفاوت امکان تغییر دارد، بهتر است استفاده شود، مثال های ساده ای میتوان بیان کرد که استفاده وعدم استفاده تفاوت کاملا مشهود دارد ولی در نهایت تصمیم شرایط و محل واستفاده به عهده برنامه نویس ودر تخصص او است، به عنوان نمونه در کد فوق نباید استفاده شود و استفاده از کلاس Interlocked بسیار مناسب ومطمئن تر عمل میکند.
شب خوش.
:n11:
ممنون بابت توضیحاتتون . :n16:
درکد قیلی که دوستمون داده بودند اصلا فرم اولیه که قرار بود در هنگام تک کلیک باز شود اجرا نمی شد اما در این کدی که شما گذاشتید این اتفاق میفته و وقتی فرم دوم که در هنگام دابل کلیک باز می شود رو اجرا می کنیم چند ثانیه در حالت هنگ قرار میگیره سپس فرم اول هم باز می شود.
یه مشکل دیگر هم داشتم که دوستمون توضیحاتی رو دادند اما موفق نشدم.
میشه لود شدن کنترل های فرم رو در هنگام اجرا کنترل کرد؟ یا حد اقلش شاید یه پروگرس بار برای اجرای فرم بزارم بزارم که هنگام لود شدن کنترل ها نمایش داده بشه؟ مثل backgroundworker . معمولا واسه اجرای کد میشه استفاده کرد اما برای لود شدن فرم رو نمیدونم.
راهی نیست که بشه این بخش رو هم تحت کنترل قرار داد؟
سلام
... در هنگام دابل کلیک باز می شود رو اجرا می کنیم چند ثانیه در حالت هنگ قرار میگیره سپس فرم اول هم باز می شود ...
یعنی الآن مشکل حل شد؟ یا منظورتان این است که با کد فوق هم مشکل دارید و هر دوعملی که (برای Click و DblClick) نوشته اید انجام میشود؟
... یه پروگرس بار برای اجرای فرم بزارم بزارم که هنگام لود شدن کنترل ها نمایش داده بشه؟
نکته اول:
بطور معمول استخراج و آماده کردن دیتا زمان بر است و نمایش سریع اتفاق می افتد !
به عنوان نمونه در یک برنامه دیتابیسی، واکشی اطلاعات از دیتابیس مهم ترین بخش کار است که میتوان توسط ریسمان جدا انجام داد و در زمان کار یک تصویر گردشی (gif مانند) نمایش داد.
اگر UI شما به ذات (فارغ از دیتا) خیلی سنگین است، شاید نیاز به اصلاح داشته باشد، شاید حجم بالایی از سطرها را نشان میدهید ...
...
نکته دوم:
برای پروژه هایی مانند WinForm میتوانید یک پیام "لطفا منتظر بمانید..." روی فرم قرار دهید ...
بخش مورد نظر را در یک UserControl بسازید و new کنید ...
دیتاها را واکشی و bind کنید...
روی UserControl و بخش های مهم متدهایی مانند CreateHandle و CreateControl و برای ظرف ها PerformLayout را تحت BeginInvoke اجرا کنید ...
سپس UserControl را Visible کنید.
shadmehrshadow1
10-08-2016, 20:58
سلام
یعنی الآن مشکل حل شد؟ یا منظورتان این است که با کد فوق هم مشکل دارید و هر دوعملی که (برای Click و DblClick) نوشته اید انجام میشود؟
.
کدی که شما گذاشتید به طوری هست که وقتی دابل کلیک صورت می گرد عمل کلیک هم اجرا می شود. در حالی که کدی که دوست دیگرمون گذاشتند و من اون کد رو مجددا گذاشتم به درستی عمل می کرد و مشکلی توش نبود. و فقط من به جای دستور Task از Thread استفاده کردم.نمیدونم کار درستی بود یا نه.
ممنون بابت توضیحات دیگرتون :n16:
سلام
کد را درست امتحان نکرده بودم، جهت کنجکاوی خودم و افزایش اطلاعات، امتحانی انجام دادم و بظاهر درست کار کرد.
شاید باتوجه به تنظیمات رایانه شما 500 میلی ثانیه کافی نبوده و نیاز به زمان بیشتری باشد، (یادم نبود بیشتر VB کار میکنید) شاید هم به VB تبدیل کرده اید و جایی را بد تبدیل کرده اید...
البته حالا که مشکل تان حل شده، دیگر اهمیتی ندارد.
گفتم پروژه امتحانی که ساختم را اگر بدرد کسی میخورد به اشتراک بگذارم: (لینک موقت-فایل در آینده حذف خواهد شد)
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
موفق باشید. :n16:
vBulletin , Copyright ©2000-2025, Jelsoft Enterprises Ltd.