PDA

View Full Version : استفاده از چند thread به صورت همزمان



debugger
جمعه 01 شهریور 1392, 13:47 عصر
من یک لیست از آدرس وب سایت ها در برنامه ام دارم . مثلا تعدادشون 5000 تا لینک است . حالا اومدم یک تابعی نوشتم که میاد به ترتیب از اولین لینک شروع میکنه و به لینک رجوع می کنه و بعد یک کلمه را داخل اون صفحه جستجو می کنه اگر وجود داشت توی یک لیست باکس اضافه میکنه و میره لینک بعدی و همین طور الی اخر و اگر هم وجود نداشت هیچی اضافه نمی کنه و میره بعدی

در واقع شبه کد زیر را در نظر بگیرید

for (int i = 0; i < ListBoxLinks.length; i++)
{
if (getSource(ListBoxLinks.items[i]).contain("xxxxx") == true)
{
ListBoxFind.items.add(ListBoxLinks.items[i]);
}
}

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

ولی من میخوام یک textbox بزارم داخل برنامه . مثلا کاربر بیاد توش یه عددی را بنویسه مثلا 10

حالا برنامه باید بیاد 10 تا Thread ایجاد کنه و Thread1 بیاد اولین لینک از لیست را بخونه و چک کنه و thread2 بیاد دومین لینک از لیست را بخونه و الی اخر .... و thread10 بیاد دهمین لینک را بخونه و بعد از اتمام thread1 بره از یازدهمین لینک شروع کنه و thread2 بره از دوازدهمین لینک و ..... thread10 بره بیستمین لینک را بخونه و .... همینطوری تا اخر لیست پیش بره

تعداد لینک های موجود در لیست هم اصلا مشخص نیست . هر لحظه در حال افزایش است . یعنی یک تابع داره هی به تعداد لینک ها اضافه می کنه . پروسه زمانی Stop میشه که کاربر خودش stop کنه

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

امیدوارم توضیحاتم واضح بوده باشه

ممنون میشم یک راه حل برای بنده ارائه کنید

با تشکر

m_ali_gho
جمعه 01 شهریور 1392, 13:58 عصر
سلام. سوال رو خوندم اما در حد من نیست که بتونم جوابی بهش بدم. فقط یه سوال برا خودم پیش اومده. شما یه لیست باکس از tool box تو فرمت قرار میدی. اول فرض میکنیم فقط یه نخ به اسم thread1 قراره کار کنه. خب. نخ شروع به کار میکنه و تو یکی از لینک ها به یه جوابی میرسه. میاد که جوابو تو لیست باکس قرار بده اما نمیتونه چون لیست باکس رو thread1 درست نکرده!!! بنا بر این بهش دسترسی نداره. حالا برای حل این مشکل میای با کد نویسی از داخل thread1 یه لیست باکس تو فرمت ایجاد میکنی. حالا داستان اینجاست که می خوای از چند تا نخ دیگه هم استفاده کنی. خب اون نخ ها هم به این لیست باکس دسترسی ندارن به همون دلیل که گفتم. این مشکل رو چجوری می خوای حل کنی؟

debugger
جمعه 01 شهریور 1392, 14:28 عصر
دوست عزیز مشکل دسترسی به اجزای فرم از داخل ترد دیگر به دو روش قابل حل است . روش اول : روش نا امن Control.CheckForIllegalCrossThreadCalls = false;

روش دوم به اختصار control.InvokeRequired می باشد که می توانید جستجو کنید . مشکل من یه چیز دیگه هست

Mahmoud.Afrad
جمعه 01 شهریور 1392, 16:12 عصر
هر ترد میتونه یک اندیس آغازین داشته باشه و بعد از اون به تعداد تردها باید به این اندیس اضافه بشه تا اندیس بعدی بدست بیاد تا بتونه ازش استفاده کنه.
مثلا برای 10 ترد:
ترد اول ، اندیس 0و10و20و...
ترد دوم ، اندیس 1و11و21و31و...
ترد سوم ، اندیس 2و12و22و32و...
.....
ترد دهم ، اندیس 9و19و29و...

یک متغیر داخل متد ترد مینویسی تا اندیس قبلی مربوط به اون ترد رو نگه داره تا بتونی اندیس جدید رو از روی اون بدست بیاری.
منتها قبل از دسترسی به اندیس مورد نظر باید چک بشه این اندیس وجود داره یا نه ، اگر وجود داشت استفاده کنه اگر نداشت ترد به کارش خاتمه میده.

debugger
جمعه 01 شهریور 1392, 16:56 عصر
ترد را به چه صورتی بنویسم که بتونم به تابعی که داخل ترد فراخوانی میشه . پارامتر بفرستم ؟؟؟

aliagamon
جمعه 01 شهریور 1392, 17:14 عصر
فکر کنم منضورتون اینه:

Thread thread = new Thread(() => linkseaarch("http://url.domain"));
thread.Start();

Mahmoud.Afrad
جمعه 01 شهریور 1392, 18:26 عصر
متد Start یک object رو به متد منتقل میکنه. البته متد هم باید یک ورودی object داشته باشه.

private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(MyMethod);
t.Start(1);
}

private void MyMethod(object obj)
{
int index = Convert.ToInt32(obj);
MessageBox.Show(obj.ToString());
}

debugger
جمعه 24 آبان 1392, 14:13 عصر
چطوری میشه این ده تا ترد که ایجاد شده را pause کرد ؟؟؟ با thread.suspend نشد

Mahmoud.Afrad
جمعه 24 آبان 1392, 15:14 عصر
thread.suspend روی ترد جاری اصلی اثر میزاره. شما باید تردها رو در لیستی از تردها قرار بدید و اونها رو pause کنید.

FastCode
جمعه 24 آبان 1392, 15:29 عصر
http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach%28v=vs.110 %29.aspx

debugger
سه شنبه 05 آذر 1392, 23:44 عصر
thread.suspend روی ترد جاری اصلی اثر میزاره. شما باید تردها رو در لیستی از تردها قرار بدید و اونها رو pause کنید.

متدی به نام pause را نتونستم پیدا کنم .

tooraj_azizi_1035
چهارشنبه 06 آذر 1392, 09:24 صبح
سلام
ما کلاسی داریم به نام Barrier که یک هماهنگ کننده به حساب میاد در سناریوی شما 10 ترد به اون معرفی میشه و و اجرای کد فقط وقتی هر 10 ترد کارشون تموم شد ادامه پیدا میکنه:http://msdn.microsoft.com/en-us/library/system.threading.barrier(v=vs.110).aspx

به هر یک از ترد ها در این کلاس شرکت کننده گفته میشه و با متد AddParticipants شرکت کننده جدید اضافه میشه.

debugger
چهارشنبه 11 دی 1392, 17:09 عصر
من برنامه را پیاده کردم . بعد از گذشت چندین دقیقه مثلا ده دقیقه بعضی مواقع بیست دقیقه و ... خود به خود برنامه خارج میشه

در قسمت form closing نوشتم e.cancel=true

و در قسمت program.cs هم حتی با پیاده کردن کردن ایونت Application.ThreadException هم قابل رد گیری نیست .

اثر گذار نیست

FastCode
چهارشنبه 11 دی 1392, 21:35 عصر
هدفتون از سوال پرسیدن بدون کد چیه؟