PDA

View Full Version : مقابله با هنگ در اجرای حلقه‌ها



menevlster
شنبه 20 فروردین 1390, 23:29 عصر
سلام دوست عزیز
در حلقه for که مدت زمان آن بیش از یک دقیقه بطول می انجامد برای اینکه فرم برنامه حالت غیر فعال نداشته باشد چه کاری لازم است؟
در سی شارپ این مشکل به راحتی با ()Application.DoEvents قابل حل است ول در ++C چکار باید کرد؟

hi.alir
یک شنبه 21 فروردین 1390, 03:46 صبح
با Sleep 0 میشه درستش کرد. درواقع DoEvents تو دات نت هم تقریبا همینکار رو انجام میده ( چون نیتیو نیست شاید خود دات نت فریم ورک یه کارای خاصی انجام بده ). ولی در کل بهتره از این روش چه تو ++C چه تو دات نت استفاده نکنید. در عوض برای اون حلقتون یه نخ دیگه درست کنید.

menevlster
یک شنبه 21 فروردین 1390, 15:05 عصر
با Sleep 0 میشه درستش کرد. درواقع DoEvents تو دات نت هم تقریبا همینکار رو انجام میده ( چون نیتیو نیست شاید خود دات نت فریم ورک یه کارای خاصی انجام بده ). ولی در کل بهتره از این روش چه تو ++C چه تو دات نت استفاده نکنید. در عوض برای اون حلقتون یه نخ دیگه درست کنید.
دوست عزیز سلام ممنون از جواب
وجود Sleep 0 با نبود آن زیاد فرقی نداشت.
نظرتون در رابطه با استفاده از PassWindowMessages() به جای Sleep 0 چیست؟


void PassWindowMessages()
{
MSG msg;

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
}
}

لطفا نحوه ایجاد نخ را با یک مثال آموزش دهید.

hi.alir
یک شنبه 21 فروردین 1390, 21:12 عصر
وجود Sleep 0 با نبود آن زیاد فرقی نداشت.
رو CPU های چند هسته ای فرقی نداره ولی اگر تک هسته ای باشه به جای کل کامپیوتر فقط برنامه ی شما هنگ میکنه!!!!!


لطفا نحوه ایجاد نخ را با یک مثال آموزش دهید.
http://msdn.microsoft.com/en-us/library/ms682453(v=vs.85).aspx


نظرتون در رابطه با استفاده از
PassWindowMessages()
همچنان نخ رو ترجیح میدم. این کارا خطراتی داره که اگر جست و جو کنید متوجه میشید.

menevlster
یک شنبه 21 فروردین 1390, 22:14 عصر
لطفا به کد زیر توجه کنید




DWORD ThreadProcIn ( LPVOID lpData )
{
CListCtrl * pListCtrl = (CListCtrl *)lpData;
int nItem =pListCtrl.GetItemCount();
از اين به بعد دليل نامعلومي ادامه نمي يابد
return 0;
}
HANDLE m_hChannelScannThread;
void GoThread()
{
m_listctrl مربوط به کنترلي از نوع CListCtrl است
if(!m_hChannelScannThread)
m_hChannelScannThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProcIn, (LPVOID)m_listctrl, 0, 0);

WaitForSingleObject(m_hChannelScannThread, INFINITE);

CloseHandle(m_hChannelScannThread);

}




در قسمت ThreadProcIn پارامتر pListCtrl به درستی دریافت می شود ولی در گرفتن GetItemCount ایجاد خطا کرده و هنگ میکند.
با ایجاد Thread در دات نت، dataGridView را نمی توان به طور مستقیم در آن به کار برد آیا به همین دلیل در ++ C آیا pListCtrl را نیز نمی توان در ThreadProcIn بکار برد یا اشکال در جای دیگر ی است؟

hi.alir
یک شنبه 21 فروردین 1390, 22:30 عصر
نخ ها کلا غیر از این مسائل خطرات وحشتناکی رو در پیش دارند اگر مراقب نباشید که خودش یه کتاب میشه! ولی اینجا روشنه که بعد از return 0 ادامه پیدا نمی کنه. شما با return به تابع پایان میدید، چطور انتظار دارید ادامه داشته باشه؟


با ایجاد Thread در دات نت، dataGridView را نمی توان به طور مستقیم در آن به کار برد آیا به همین دلیل در ++ C آیا pListCtrl را نیز نمی توان در ThreadProcIn بکار برد یا اشکال در جای دیگر ی است؟
اگر عمومی باشه مشکلی پیش نمیاد. ولی اگر عمومی نباشه یه مقدار کار بیشتر میبره که می تونید تو MSDN نگاه کنید.

menevlster
یک شنبه 21 فروردین 1390, 22:34 عصر
دوست عزیز در قسمت ThreadProcIn مرحله دریافت nItem صورت نمی گیرد یعنی در مرحله GetItemCount برنامه هنگ می کند

hi.alir
یک شنبه 21 فروردین 1390, 22:59 عصر
int nItem =pListCtrl.GetItemCount();
گمونم اینجا یه syntax error داره!؟ pListCtrl یه اشاره گر هست. باید به یکی از دو حالت زیر بنویسید.
int nItem =pListCtrl->GetItemCount();
یا
int nItem = (*pListCtrl).GetItemCount();

البته من زیاد با نخ ها کار نکردم، در حد همون چند صفحه ی MSDN میدونم، ولی غیر از مورد بالا گفتم باید lpData ای که به نخ فرستاده میشه یه متغیر یا ثابت عمومی باشه در غیر این صورت باید از روش دیگری (احتمالا) استفاده کرد که تو MSDN باید باشه.

menevlster
یک شنبه 21 فروردین 1390, 23:18 عصر
می بخشید منظور شما از متغیر یا ثابت عمومی این می تونه باشد که pListCtrl را بصورت public در داخل یک کلاس تعریف شود یا به صورت static در خارج از کلاس؟

hi.alir
دوشنبه 22 فروردین 1390, 11:46 صبح
global در کل برنامه. ( اشتباه گفتم عمومی، منظورم سراسری بود )
مثل
int globalvarialbe
int main()
{
....
}

البته میگم میشه مثلا global هم تعریف نکرد ولی من نحوه ی دسترسی به اونا رو بلد نیستم. اگر در مورد multi threading تو c++ جست جو کنید حتما پیدا می کنید.

pe32_64
پنج شنبه 05 خرداد 1390, 23:04 عصر
تو msdn گفته شده که obj های mfc را از یک thread به thread دیگه ای منتقل نکنید(مشکل شما)
البته با انجام Synchronization در بعضی شرایط انجام پذیر است