PDA

View Full Version : سوال: دسترسی به کنرل های فرم در داخل thread



debugger
پنج شنبه 28 مرداد 1389, 17:55 عصر
سلام دوستان

من برنامه ای نوشتم که وقتی روی یک دکمه کلیک می کنی یه کاری را انجام بده اما به دلیل سنگین بودن کار مورد نظر برنامه هنگ میکنه

حالا اومدم از thread استفاده کردم که مشکل اینه که کد هایی که نوشتم را بردم داخل اون thread مورد نظر و برنامه ارور میده میگه فلان کنترل را نمی شناسم

به کد ها توجه کنید

از داخل کد های button مورد نظر . کد ها ور داشتم و کد های زیر را نوشتم




private void button3_Click(object sender, EventArgs e)
{
Thread run = new Thread(new ThreadStart(runsend));
run.Start();
//

}



حال اومدم تابع runsend را به صورت زیر نوشتم



private void runsend()
{
if (comboBox1.SelectedItem.ToString().Trim() == "123456789")
{
///
}
label9.Text = "Sent : " + checkedListBox1.CheckedItems.Count.ToString();
///// code haye man //////
}


ارور برنامه هم اینه

Cross-thread operation not valid: Control 'comboBox1' accessed from a thread other than the thread it was created on.

ممنون میشوم کمک کنید

m_d6712
پنج شنبه 28 مرداد 1389, 18:05 عصر
یک راه وجود داره که فعلا کارتو راه می اندازه! این کد رو یک بار در Load برنامت Run کن! یا قبل شروع tHREAD



Control.CheckForIllegalCrossThreadCalls = False


اما این روش برای پروژه های بزرگ مناسب نیست!

debugger
پنج شنبه 28 مرداد 1389, 18:38 عصر
اقا خیلی ممنون این کد کار منو راه انداخت . نمی دونم چطوری ازتون تشکر کنم .
راستی راه حل اصولیش چطوریه ؟؟؟

hojjatshariffam
پنج شنبه 28 مرداد 1389, 18:45 عصر
می تونی این کد رو



if(combobox1.SelectedText.toString()=="1234")
flag=true;

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



if(Flag)
//.....


کنترل های فرم چون در لایه UI قرار دارد نخ های دیگر نمی توانند به آن دسترسی داشته باشند ، مگر آنکه خودمون اجازه غیرقانونی بدهیم که دوستمون در پست بالا گفتند

hojjatshariffam
پنج شنبه 28 مرداد 1389, 18:49 عصر
اقا خیلی ممنون این کد کار منو راه انداخت . نمی دونم چطوری ازتون تشکر کنم .
راستی راه حل اصولیش چطوریه ؟؟؟
راه اصولیش همون متغیر های سراسری در فرم هست (اگه اصول شئ گرائی رو نقض نکنه)
ضمنا می تونی از BackGroundWorker هم استفاده کنی

debugger
پنج شنبه 28 مرداد 1389, 19:08 عصر
ممنون از توضیحات خوبت . اولش خواستم از متغیر های سراسری استفاده کنم (مثل وقتی که میخواهیم مقداری از یک فرم به فرم دیگر پاس بدهیم) . ولی بدش دیدم کنترل ها خیلی زیادن .

خلاصه این یک خط کد باعث شد ده ها خط کد ننویسم .

باز هم ممنونم

Saeed.Masoumi
پنج شنبه 28 مرداد 1389, 19:12 عصر
سلام
این مشکل زمانی پیش می آید که بخواین متعلقات یک نخ را در نخ دیگری تغییر دهید مانند تغییر در کنترل ها که بخشی از نخ UI است در نخی دیگر.
راه حل اصلی این کار استفاده از کنترل BackgroundWorker است و برای تغییر در UI استفاده از متد Report Progress توصیه میشود.
توجه کنید که برای استفاده از این متد باید خاصیت مربوط به آن را نیز True کنید.
توجه :استفاده از این روش:
Control.CheckForIllegalCrossThreadCalls = False
کار اشتباهی است - و این خاصیت اشتباه تنها برای سازگاری برنامه های قدیمی تر هنوز هم پابرجاست.
این پست (http://www.barnamenevis.org/forum/showpost.php?p=369771&postcount=11)جناب mehdi.mousavi (http://barnamenevis.org/forum/member.php?u=41233) رو توجه نمایید.

m_d6712
پنج شنبه 28 مرداد 1389, 20:11 عصر
باید خودت دسترسی Threat های خودت رو با یک Module کنترل کنی! که این ماژول همون کار با BackgroundWorker هست که دوستمون در پست قبلی گفتند! اگر یه جستجو بکنی توی نت خیلی سریع راه رو پیدا میکنی! این کار بهت کمک میکنه!
در واقع باید کدی بنویسی که برای دسترسی همزمان دو یا چند Thread رو به یک شی محدود کنه!

همون طور که دوستان گفتند
Control.CheckForIllegalCrossThreadCalls = False

راه مناسبی نیست

r00tkit
پنج شنبه 28 مرداد 1389, 21:01 عصر
من خسته شدم از بس حرف های تکراری زدید بسه دیگه !!!!!

در مورد InvokeRequired Property

و متود invoke یا begininvoke سرچ کنید

این ساده ترین راه قانونی هستش

modern_payam
یک شنبه 25 اردیبهشت 1390, 12:14 عصر
سلام ممنون از کدی که گذاشته اید خیلی بدردم خورد.:تشویق:

tooraj_azizi_1035
یک شنبه 25 اردیبهشت 1390, 15:05 عصر
سلام،
این منبع: http://msdn.microsoft.com/en-us/library/ms171728.aspx
عنوان:
How to: Make Thread-Safe Calls to Windows Forms Controls