PDA

View Full Version : نحوه خاتمه دادن یا استفاده از synchronize در یک thread که از کد sendmessage در آن استفاده شده.



arash_ebrahimi_nk
پنج شنبه 31 مرداد 1392, 00:18 صبح
دوستانی که در زمینه کار با thread ها تجربه دارن اگه کمک کنن ممنون میشم.

فرض کنید یک thread رو استارت میکنید و در خط بعدی کد خودتون میخواهید از نتیجه کار thread استفاده کنید یعنی در حقیقت میخواهید صبر کنید تا thread کار خودش رو بطور کامل انجام بده.

من معمولا اینطوری کد مینویسم
while true do
if thread1.finished then
break

و اگه از پیام رسانی در اون thread استفاده شده باشه به این صورت
while not Thread1.Finished do
Application.ProcessMessages;

میخوام بدونم راه درست و اصولیش چیه از event‌ استفاده کردم برای thread‌ که از sendmessage توش استفاده شده جواب نداد.

از قبل تشکر میکنم.

Felony
پنج شنبه 31 مرداد 1392, 10:09 صبح
من معمولا اینطوری کد مینویسم

یا پیغمبر ... :)

اولا که اون Application.ProcessMessages در برنامه های MultiThreaded ی که از Message Sync به عنوان Synchronization Object استفاده کردن ممکنه بدجوری دردسر ساز بشه .

دوما ، من هرچقدر فکر میکنم نمیفهمم ساخت این ترد به این روش به چه درد میخوره ؟! ترد رو میسازن تا بار پردازشی رو بین تردها تقسیم کنن تا باعث کند شدن ، فریز شدن و در کل بیش از حد به Wait State رفتن یک ترد نشن ، شما که میخوای صبر کنی تا تردت یه کاری بکنه بعد نتیجش رو تو خط بعدی استفاده کنی در تحلیل این مورد مشکل داری ، این که شد همون آش و هون کاسه ! با این تفصیر به نظر میاد از ترد فقط برای جلوگیری از فریز شد UI برنامت استفاده میکنی که در این صورت بازم کار درستی انجام ندادید .

شما باید عملیات های مورد نیاز رو بین تردهای مختلف و در متدهای مختلف اونها بشکنید و تقسیم کنید ، UI وظیفه ای در قبال انجام عملیات سنگین نداره ، فقط باید یک واسط برای دریافت اطلاعات و نمایش اونها باشه ، همین ، برای هماهنگ کردن تردها و متدها باید از Synchronization Object ها استفاده بکنید که انواع مختلفی دارن ( Mutex , Event , Critical Section و ... ) ، دلفی کلاس هایی برای این موارد پیاده سازی کرده که کار مشا رو در استفاده از API های مربوط به این روش ها آسونتر میکنه ، مثلا کلاس TEvenet ، این کلاس ها اکثرا در کتابخانه SyncObjs پیاده سازی شدن .

در آخر اگر تو زمینه برنامه های MultiThread تازه وارد هستین ، استفاده از کتابخانه های خود دلفی با اینکه بسیار ساده و بی دردسر هست ولی ریزکاری های خاص خودش رو داره و با توجه به اینکه Embarcadero این موراد رو اصلا خوب Document نکرده باید یه کفش آهنی بپوشی و دنبال خورده Document ها و گاها چرندیات و ... که این و اون تفت دادن باشی و به در شما نخواهد خورد ، بنابراین استفاده از کتابخانه های آماده ای مثل OmaniThread با اینکه پیچیدگی های خاص خودش رو داره ، ولی با توجه به داکیومنت ها و مثال های خوبش علاوه بر کاربرهای Advance برای یک کاربر تازه وارد در MultiThread هم مناسب هست .

روز خوش .

arash_ebrahimi_nk
پنج شنبه 31 مرداد 1392, 10:28 صبح
یا پیغمبر ... :)

اولا که اون Application.ProcessMessages در برنامه های MultiThreaded ی که از Message Sync به عنوان Synchronization Object استفاده کردن ممکنه بدجوری دردسر ساز بشه .

دوما ، من هرچقدر فکر میکنم نمیفهمم ساخت این ترد به این روش به چه درد میخوره ؟! ترد رو میسازن تا بار پردازشی رو بین تردها تقسیم کنن تا باعث کند شدن ، فریز شدن و در کل بیش از حد به Wait State رفتن یک ترد نشن ، شما که میخوای صبر کنی تا تردت یه کاری بکنه بعد نتیجش رو تو خط بعدی استفاده کنی در تحلیل این مورد مشکل داری ، این که شد همون آش و هون کاسه ! با این تفصیر به نظر میاد از ترد فقط برای جلوگیری از فریز شد UI برنامت استفاده میکنی که در این صورت بازم کار درستی انجام ندادید .

شما باید عملیات های مورد نیاز رو بین تردهای مختلف و در متدهای مختلف اونها بشکنید و تقسیم کنید ، UI وظیفه ای در قبال انجام عملیات سنگین نداره ، فقط باید یک واسط برای دریافت اطلاعات و نمایش اونها باشه ، همین ، برای هماهنگ کردن تردها و متدها باید از Synchronization Object ها استفاده بکنید که انواع مختلفی دارن ( Mutex , Event , Critical Section و ... ) ، دلفی کلاس هایی برای این موارد پیاده سازی کرده که کار مشا رو در استفاده از API های مربوط به این روش ها آسونتر میکنه ، مثلا کلاس TEvenet ، این کلاس ها اکثرا در کتابخانه SyncObjs پیاده سازی شدن .

در آخر اگر تو زمینه برنامه های MultiThread تازه وارد هستین ، استفاده از کتابخانه های خود دلفی با اینکه بسیار ساده و بی دردسر هست ولی ریزکاری های خاص خودش رو داره و با توجه به اینکه Embarcadero این موراد رو اصلا خوب Document نکرده باید یه کفش آهنی بپوشی و دنبال خورده Document ها و گاها چرندیات و ... که این و اون تفت دادن باشی و به در شما نخواهد خورد ، بنابراین استفاده از کتابخانه های آماده ای مثل OmaniThread با اینکه پیچیدگی های خاص خودش رو داره ، ولی با توجه به داکیومنت ها و مثال های خوبش علاوه بر کاربرهای Advance برای یک کاربر تازه وارد در MultiThread هم مناسب هست .

روز خوش .

ممنون به خاطر مطالب مفیدی که نوشتید.
در حقیقت یه برنامه کم حجم دارم که Enumwindows و enumchildwindws رو فراخوانی میکنه که من این دو تا در داخل یک ترد قرار دادم که UI فریز نشه. و چون در در داخل EnumWindowsProc از Sendmessage برای گرفتن caption یک پنجره استفاده کردم دچار مشکل شدم.
از طرفی این برنامه بزرگی نیست که بخوام از کتابخانه های multithread استفاده کنم و کم حجم بودنش هم برام مهمه. راه حلی وجود داره که بتونم به درستی به thread ای که ساختم خاتمه بدم؟

arash_ebrahimi_nk
شنبه 02 شهریور 1392, 15:54 عصر
کمی توی اینترنت گشتم و دیدم که روشی که کد نوشتم تا حدودی درسته و راه متداولش همون Application.ProcessMessage هست.
راهنمایی که از این لینک (http://stackoverflow.com/questions/16908253/wait-for-thread-without-freezing-the-application)گرفتم باعث شد بتونم الگوریتم بهتر و کد بهینه تری بنویسم.

بازم تشکر میکنم.