PDA

View Full Version : سوال: چگونگی کار با Thread ها



hhojjatt
شنبه 17 بهمن 1388, 11:18 صبح
سلام دوستان اگه کسی مطلبی در باره کار با Thread ها داره لطفا اینجا بذاره و اگه می تونه توضیح بده متشکر می شوم احتیاج زیادی به این مطلب دارم متشکرم

Sharif Lotfi
شنبه 17 بهمن 1388, 16:40 عصر
من هم نياز دارم تا در اين مورد بيشتر بدانم
فكر كنم براي اجراي همزمان چند عمليات مثل كار كردن يك پروسس بار در هنگام فعاليت يك حلقه و ... كاربرد دارد
دوستاني كه اطلاعاتي دارند لطفا كمك كنند

H2K
شنبه 17 بهمن 1388, 18:04 عصر
سلام ،
این مطلب رو بخونین خوبه کمک می‌کنه بهتون موفق باشین
Multi threaded Programming (http://www.codersengine.com/tutorials-forum.html?func=view&catid=8&id=238#238)

Sharif Lotfi
دوشنبه 19 بهمن 1388, 17:38 عصر
كسي از دوستان هست كه يكم بيشتر روشنمون كنه ؟

cimiarnm
دوشنبه 19 بهمن 1388, 18:13 عصر
با سلام
هرچند در این زمینه من چیز زیادی بارم نیست ولی تا جاییکه بلدم براتون شرح میدم.
فرض کنید برنامه ای دارین و در آن برنامه قرار است فشردن یک کلید برنامه یک کار سنگین و دراز مدتی را آغاز کند مثلا 10000 تا عدد رو توی یک لیست باکس وارد و نمایش دهد یا بخواهد به پایگاه داده متصل شود و .. در حالت عادی اگر شما بصورت عادی برنامه ریزی کنید زمانی که کاربر کلیک میکند برنامه به حالت فریز میرد یعنی مثلا قفل میکند و کاربر مجبور است صبر کند تا عملیات مورد نظر تمام شود واین ایراد است. حتما دیده ایدکه ویندوز وقتی فایلی را از جایی به جایی کپی میکند یک پروگرس بار نمایش میدهد و شما میتوانید حتی به کار های دیگری هم مشغول شوید چون ویندوز چند نخی است . برای تعریف نخ در برنامه شما باید بصورت زیر عمل کنید ابتدا یک کلاس تعریف کنید


publicclassMyThread
}
functions
{

در داخل این کلاس توابعی را تعریف کنید مثلا یک تابع برای اتصال به پایگاه داده مثل زیر


publicstaticvoid BackUpdataBase()
{
action1
}

حالا در برنامه خود میتوانید نخهایی را تعریف کنید بصورت زیر


Thread T2 = newThread(newThreadStart(MyThread.BackUpdataBase)) ;


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


T2.Start();

نخ شروع به اجرا میکند.
من خودم سئوالات زیادی در مورد نخ ها دارم خوشحال میشم در این مورد بحث کنیم مثلا اینکه اگر به کمک یک نخ فرمی را نمایش دادیم بعد از تمام شدن نخ چطور ان فرم را ببندیم؟

Sharif Lotfi
یک شنبه 25 بهمن 1388, 13:10 عصر
با تشكر از دوست عزيزمون
از دوستان كسي هست كه ما رو بيشتر راهنمايي كنه . من برنامه اي دارم كه يكي دو جاي اون زمان خيلي زيادي رو مي بره تا كار محاسبه انجام بشه و امكان قطع اون رو تو كد ندارم
حالا مي خوام يه دكمه تعريف كنم كه كاربر هر وقت خواست از ادامه ي كار منصرف بشه اونو بزنه و كار محاسبه وسط حلقه قطع بشه تا جايي كه اطلاع دارم تنها راه همين Thread هستش ولي با راهنمايي هاي دوستان هم هنوز كارم راه نيفتاده

hhojjatt
یک شنبه 25 بهمن 1388, 16:49 عصر
من خودم سئوالات زیادی در مورد نخ ها دارم خوشحال میشم در این مورد بحث کنیم مثلا اینکه اگر به کمک یک نخ فرمی را نمایش دادیم بعد از تمام شدن نخ چطور ان فرم را ببندیم؟


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


فکر کنم برای اجرای همزمان چند عملیات مثل کار کردن یک پروسس بار در هنگام فعالیت یک حلقه و ... کاربرد دارد
یک متغیر bool تعریف کنید اگه داخل کلاس دیگه است استاتیکتعریف کنیدو وقتی دکمه کنسل زده شد ان را مقدار دهی کنید و در داخل تابع یا حلقه و یا هرجای که در حقیقت ترد است کد زیر را بر حسب نیاز بنویسید



mytread()
{
if (bool==true)
{
Thread.CurrentThread.Abort();
Thread.ResetAort();
this.close();
{
{

البته من خودم دارم تازه یاد میگیرم واسه همین خیلی مهارت ندارم
دستور زیر هم نشون میده ترد تموم شده یا نه

Thread.CurrentThread.IsAlive

gwbasic
یک شنبه 25 بهمن 1388, 18:02 عصر
با تشکر از دوست عزیزمون
از دوستان کسی هست که ما رو بیشتر راهنمایی کنه . من برنامه ای دارم که یکی دو جای اون زمان خیلی زیادی رو می بره تا کار محاسبه انجام بشه و امکان قطع اون رو تو کد ندارم
حالا می خوام یه دکمه تعریف کنم که کاربر هر وقت خواست از ادامه ی کار منصرف بشه اونو بزنه و کار محاسبه وسط حلقه قطع بشه تا جایی که اطلاع دارم تنها راه همین Thread هستش ولی با راهنمایی های دوستان هم هنوز کارم راه نیفتاده
برای این کار کامپوننتی به نام Backgroundworker وجود دارد که باعث می شود کار زمانبر ما در Thread دیگری اجرا شود و در ضمن قابلیت کنسل کردن و گزارش روند کار را نیز دارد.
برای آشنایی کامل با backgroundworker به لینک زیر مراجعه کنید:
http://barnamenevis.org/forum/showthread.php?t=200544&highlight=%D8%A2%D9%85%D9%88%D8%B2%D8%B4+Backgroun dworker

ali-asheq
شنبه 15 اسفند 1388, 17:59 عصر
سلام دوستان میخوام با thread برنامه ای بنویسم که در ساعتی خاص فرم اجرا شود .تشکر

ArenaSmi
شنبه 15 اسفند 1388, 20:17 عصر
با سلام
هرچند در این زمینه من چیز زیادی بارم نیست ولی تا جاییکه بلدم براتون شرح میدم.
فرض کنید برنامه ای دارین و در آن برنامه قرار است فشردن یک کلید برنامه یک کار سنگین و دراز مدتی را آغاز کند مثلا 10000 تا عدد رو توی یک لیست باکس وارد و نمایش دهد یا بخواهد به پایگاه داده متصل شود و .. در حالت عادی اگر شما بصورت عادی برنامه ریزی کنید زمانی که کاربر کلیک میکند برنامه به حالت فریز میرد یعنی مثلا قفل میکند و کاربر مجبور است صبر کند تا عملیات مورد نظر تمام شود واین ایراد است. حتما دیده ایدکه ویندوز وقتی فایلی را از جایی به جایی کپی میکند یک پروگرس بار نمایش میدهد و شما میتوانید حتی به کار های دیگری هم مشغول شوید چون ویندوز چند نخی است . برای تعریف نخ در برنامه شما باید بصورت زیر عمل کنید ابتدا یک کلاس تعریف کنید


publicclassMyThread
}
functions
{

در داخل این کلاس توابعی را تعریف کنید مثلا یک تابع برای اتصال به پایگاه داده مثل زیر


publicstaticvoid BackUpdataBase()
{
action1
}

حالا در برنامه خود میتوانید نخهایی را تعریف کنید بصورت زیر


Thread T2 = newThread(newThreadStart(MyThread.BackUpdataBase)) ;


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


T2.Start();

نخ شروع به اجرا میکند.
من خودم سئوالات زیادی در مورد نخ ها دارم خوشحال میشم در این مورد بحث کنیم مثلا اینکه اگر به کمک یک نخ فرمی را نمایش دادیم بعد از تمام شدن نخ چطور ان فرم را ببندیم؟

سلام يه سوال كوچولو ميخوام يه فرم داشته باشم كه با كليك يه دكمه چند تا برنامه پشت هم شروع به نصب بشن به نظر شما با ترد ميشه اينكارو كرد؟
مرسي

bpzone
دوشنبه 06 اردیبهشت 1389, 14:28 عصر
من یک برنامه نوستم که در اون ممکن هست که 100 نخ ایجاد و فراخونی بشه .
چطوری می تونم چک بکنم که عملیات مورد نظر هم نخ به اتمام رسیده و اون رو چطوری می تونم از بین ببرم که برنامه سنگین کار نکنه :افسرده:

JohnSmith
دوشنبه 06 اردیبهشت 1389, 15:30 عصر
به نظرم از يك منيجر مركزي همراه با متغيرهاي عمومي در يك كلاس عمومي راه حل ساده اي باشد.

البته احتمالا استاندارد نيست ولي كار را راه مي اندازد.

bpzone
دوشنبه 06 اردیبهشت 1389, 15:38 عصر
میشه کمی بیشتر توضیح بدید که دقیقاً منظورتون چی هست :افسرده:

bpzone
سه شنبه 07 اردیبهشت 1389, 07:56 صبح
دوستان عزیز
فرض کنید 1000 کلاینت داریم که قرار هست یک سری فایل از سرور به این کلاینت ها یا برعکس منتقل بشه ...
من می خوام 10 ترد ایجاد کنم و کلاینت ها رو بزارم توی یک صف
و در هر لحظه سرور به 10 تا کلاینت ( 10 ترد ) اتصال برقرار کنه
و هر کدوم از ترد ها که مارش تموم بشه، تابع اصلی این رو بفهمه و از صف کلاینت ها یک کلاینت دیگه رو خارج کنه و دوباره ترد رو ایجاد کنه
1- چه جوری می تونم بفهمم که یک ترد کارش تموم شده ؟
2- چه جوری میشه فهمید که یک ترد به مشکل برخورده ؟
3- چه جوری بعد از اتمام کار یک ترد، اون رو از بین ببرم ؟

bpzone
سه شنبه 07 اردیبهشت 1389, 12:18 عصر
و سوال بعدی :
4- یکی از این ترد ها قرار هستکه یک متغیر در برنامه اصلی رو مقدار دهی بکنه !
حالا من چه جوری می تونم زمانی که اون متغیر تغییر پیدا کرد ، متوجه بشم، بدون اینکه مدام بخوام اون متغیر رو چک کنم و برنامه رو درگیر کنم ؟!؟!؟! :افسرده:

FastCode
سه شنبه 07 اردیبهشت 1389, 14:32 عصر
و سوال بعدی :
4- یکی از این ترد ها قرار هستکه یک متغیر در برنامه اصلی رو مقدار دهی بکنه !
حالا من چه جوری می تونم زمانی که اون متغیر تغییر پیدا کرد ، متوجه بشم، بدون اینکه مدام بخوام اون متغیر رو چک کنم و برنامه رو درگیر کنم ؟!؟!؟! :افسرده:


برای مورد شما هرگز هرگز هرگز هرگز thread و TCP پیشنهاد نمیشه به چند دلیل:
1.ERORRCODE = 0xc0000007 = STATUS_PAGEFILE_QUOTA
برای جلوگیری از این خطا به دو فروند IntelCore i7 نیاز دارید:گیج:
چرا؟
چون هر thread 24 kb از cache پردازنده شما رو نیاز داره.

2.سرعتت مثل کشتی به گل نشسته میشه.
3.مدیریتش خیلی سخته.
4.configuraation خیلی زیادی نیاز داری.

پس چه کا رکنی؟
شما باید از RUDP یا UDP در صورت کم اهمیت بودن اطلاعات استفاده کنی.
چرا؟
1.فقط به چند تا thread نیاز دارید.
2.configuarion به سختی TCP نیست(10% راحتتره)
3.سرعتش بیشتره.
4.اندازه header توش کمتره
5.به علت تعداد thread کم دچار BSoD نمیشی.

bpzone
سه شنبه 07 اردیبهشت 1389, 15:18 عصر
برای مورد شما هرگز هرگز هرگز هرگز thread و TCP پیشنهاد نمیشه به چند دلیل:
1.ERORRCODE = 0xc0000007 = STATUS_PAGEFILE_QUOTA
برای جلوگیری از این خطا به دو فروند IntelCore i7 نیاز دارید:گیج:
چرا؟
چون هر thread 24 kb از cache پردازنده شما رو نیاز داره.

2.سرعتت مثل کشتی به گل نشسته میشه.
3.مدیریتش خیلی سخته.
4.configuraation خیلی زیادی نیاز داری.

پس چه کا رکنی؟
شما باید از RUDP یا UDP در صورت کم اهمیت بودن اطلاعات استفاده کنی.
چرا؟
1.فقط به چند تا thread نیاز دارید.
2.configuarion به سختی TCP نیست(10% راحتتره)
3.سرعتش بیشتره.
4.اندازه header توش کمتره
5.به علت تعداد thread کم دچار BSoD نمیشی.

برای انتقال فایل ها از برنامه زیر استفاده می کنم



private void btn_copy_Click(object sender, EventArgs e)
{
DirectoryCopy(@"\\210.12.0.233\ncr\archive", @".\temp_ncr_new", true);
}

private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();

// If the source directory does not exist, throw an exception.
if (!dir.Exists)
{
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceDirName);
}

// If the destination directory does not exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}


// Get the file contents of the directory to copy.
FileInfo[] files = dir.GetFiles();

foreach (FileInfo file in files)
{
// Create the path to the new copy of the file.
string temppath = Path.Combine(destDirName, file.Name);

// Copy the file.
file.CopyTo(temppath, false);
}

// If copySubDirs is true, copy the subdirectories.
if (copySubDirs)
{

foreach (DirectoryInfo subdir in dirs)
{
// Create the subdirectory.
string temppath = Path.Combine(destDirName, subdir.Name);

// Copy the subdirectories.
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
اما سوالاتم در مورد نحوه کار با ترد همچنان باقی هست
من برای انتقال فایل ها به سرور با استفاده از برنامه فوق ، تقریباً 10 ترد حداکثر به وجود میارم
و برنامه رو با همون ترد ها انجام میدم ؟!؟!

اما مجدداً و همچنان سوالات باقیست :عصبانی++:

bpzone
سه شنبه 07 اردیبهشت 1389, 23:33 عصر
دوستان عزیز
4 تا سوال ما رو کی جواب میده :بوس:

bpzone
سه شنبه 04 خرداد 1389, 09:54 صبح
چه جوری می تونم بفهمم که یک ترد کارش تموم شده ؟

چه جوری میشه فهمید که یک ترد به مشکل برخورده ؟

چه جوری بعد از اتمام کار یک ترد، اون رو از بین ببرم ؟

چه جوری ترد ها می تونن با هم ارتباط داشته باشن ؟

میشه یک ترد رو متوقف کرد و بعد دوباره از ادامه فعالش کرد ؟

jigily
شنبه 24 اردیبهشت 1390, 18:37 عصر
حتما بايد از كلاس استفاده كنيم؟

haghft
شنبه 24 اردیبهشت 1390, 19:55 عصر
چه جوری می تونم بفهمم که یک ترد کارش تموم شده ؟

چه جوری میشه فهمید که یک ترد به مشکل برخورده ؟

چه جوری بعد از اتمام کار یک ترد، اون رو از بین ببرم ؟

چه جوری ترد ها می تونن با هم ارتباط داشته باشن ؟

میشه یک ترد رو متوقف کرد و بعد دوباره از ادامه فعالش کرد ؟





حالات یک ترد با خاصیت ThreadState میتوانید بفهمید.
برای از بین بردن یک ترد از theard.Join(); یا theard.Abort(); استفاده کنید.
برای متوقف کردن یک ترد از theard.Suspend(); و برای ادامه آن از theard.Resume(); استفاده کنید.
برای ارتباط دو ترد هم از این مقاله استفاده کن:
http://www.codeproject.com/KB/threads/threadpoolmanager.aspx

jigily
یک شنبه 25 اردیبهشت 1390, 15:26 عصر
Cross-thread operation not valid
نميدونم چرا اين پيغام ميده..كسي ميدونهههههههههه؟؟.

tooraj_azizi_1035
یک شنبه 25 اردیبهشت 1390, 15:35 عصر
سلام،
هر برنامه در ویندوز به عنوان یک Process شناخته می شه یعنی یک واحد اجرایی مستقل از سایرین. اما خود پردازش به تنهایی معنا ندارد، یک پردازش از حداقل یک یا بیش از یک نخ اجرایی Thread تشکیل شده است. Thread ها فضای پشته خاص خودشان را دارند و منابع پردازش مادر توسط Thread هایش به مشترک استفاده می شود Thread ها می توانند کد یکسانی را اجرا کنند و به متغیر های سراسری و منابع دیگر دسترسی دارند. در کل علت وجود Thread ها توزیع بار پردازش میان چند نخ اجرایی در جهت تسریع در رسیدن به خروجی می باشد.
برای اطلاعات بیشتر Windows Internals را در گوگل جستجو کنید.

haghft
یک شنبه 25 اردیبهشت 1390, 18:05 عصر
Cross-thread operation not valid
نميدونم چرا اين پيغام ميده..كسي ميدونهههههههههه؟؟.
اون کدی که دیباگر با این ارور هایلایت میکنه رو در درون این کد بگذارید:
Invoke(new MethodInvoker(delegate {کد مورد نظر}));

jigily
دوشنبه 26 اردیبهشت 1390, 00:13 صبح
اون کدی که دیباگر با این ارور هایلایت میکنه رو در درون این کد بگذارید:
Invoke(new MethodInvoker(delegate {کد مورد نظر}));


دوست عزيز مشكل حل شد واقعا ممنونم...
اما ميشه توضيح بديد چه مشكلي داشت تا متوجه هم بشم...

haghft
دوشنبه 26 اردیبهشت 1390, 08:34 صبح
ببینید یه مسأله ای هست که اجزای دو ترد به صورت عادی نمی توانند با هم ارتباط برقرار کنند بنابراین فرم و کنترل ها و کلا اجزای UI که در UI theard پیاده سازی می شوند و دستوراتی که شما در یک ترد جدید پیاده سازی میکنید نمی توانند باهم به صورت عادی ارتباط برقرار کنند و این مشکل پیش می آید پس باید با متد Invoke آن ها را صدا زد.

hassan181
دوشنبه 14 مهر 1393, 10:04 صبح
دمت گرم خان! مشکل منم حل شد LIKE

elahe1393
دوشنبه 14 مهر 1393, 14:38 عصر
سلام من تو پروژه ام نیاز دارم بصورت موازی از یه پورت سریال داده دریافت کنم بعد جای دیگه از این داده های استفاده کنم داده های دریافتی رو به یه تکست باکس اضافه می کنم و در جای دیگه از تکست این تکست باکس استفاده می کنم تا رشته داخلشو پردازش کنم
کد اون بخش اینه
private void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
string str;
if (this.InvokeRequired)
{
str = Encoding.ASCII.GetString(e.Data);
this.BeginInvoke(new MethodInvoker(delegate
{
txtRecieveData.AppendText(str);
}));
return;
}
}
حالا وقتی اجرا میشه تو کدی که به تکست باکس رشته اضافه میشه این خطا رخ میده مشکل چیه؟
124276

elec60
سه شنبه 15 مهر 1393, 22:17 عصر
http://www.albahari.com/threading/