کار با Thread و خطا در هنگام اجرای Thread
باسلام
من تو پروژه ای که نوشتم نزدیک به 18 تا comboBox دارم و میخوام نام کلیه رنگ های سیستم رو تو اونها قرار بدم.
اما چون تعداد اونها زیاد هست هنگام لود فرم کمی مکث میکنه. میخوام این تابع تو یه نخ جداگانه ای اجرا بشه.
برای این منظور متغیر ها و توابعی که تعریف کردم به شکل زیر هستش:
متغیرهای عمومی:
private System.Threading.Thread thMain;
private ComboBox[] cmb;
private string[] ColorName;
سازنده فرم:
public FSetting()
{
InitializeComponent();
cmb = new ComboBox[]
{
cmbColorbtnDelete,cmbColorbtnEdit,cmbColorbtnNew,c mbColorbtnSave,cmbColorbtnSearch,cmbColorForm,
cmbColorLabel,cmbColorTabControlColor1,cmbColorTex tBox,cmbColorbtnDeleteText,cmbColorbtnEditText,
cmbColorbtnNewText,cmbColorbtnSaveText,cmbColorbtn SearchText,cmbColorTextBoxText,cmbColorTabControlC olor2,
cmbColorTabItem,cmbColorTabItemSelect
};
ColorName = Enum.GetNames(typeof(KnownColor));
Array.Sort(ColorName);
هنگام لود:
thMain = new System.Threading.Thread(new System.Threading.ThreadStart(SetItemComboBox));
thMain.Start();
و تابعی که میخوام تو یه نخ جداگانه ای انجام بشه:
private void SetItemComboBox()
{
foreach (string item in ColorName)
{
foreach (ComboBox c in cmb)
c.Items.Add(item);
}
thMain.Abort();
}
و خطای صادر شده ای که در قسمت قرمز رنگ مشخص کردم
Cross-thread operation not valid: Control 'cmbColorbtnDelete' accessed from a thread other than the thread it was created on.
متشکر
علی پاییزی
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
من میتدی هستم ولی یه چیزایی خونده بودم که باید از delegate استفاده کنی.
ولی یکی از دوستانم اینو بهم پیشنهاد داد که درست هم کار می کرد :
نقل قول:
Control.CheckForIllegalCrossThreadCalls = false;
با تشکر
سینا شیری همدانی:بامزه:
:لبخند:
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
cmb و ColorName رو در یک متد جداگانه مقدار دهی کنید.
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
با سلام
راه اصولی اینکه باید از Invoke استفاده کنی
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
نقل قول:
نوشته شده توسط
salehbagheri
cmb و ColorName رو در یک متد جداگانه مقدار دهی کنید.
الان pc ايم و پروزه ام دمه دست نيست اما چك ميكنم.
بنظر شما مشكل در مقدار دهي cmb هست؟ آخه همين مقدار دهي رو هم تو همون تابع قبل از حلقه انجام داده بودم اما باز همين خطا صادر شده بود.
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
فکر کنم من ده ها بار شاهد پرسیدن این مورد در فروم بودم!
شما نمی تونید از Thraed جداگانه (یعنی Thraed ای غیر از Thread اصلی فرم) با عناصر روی فرم کار کنید : Thread-Safe Calls to Windows Forms Controls؛ برای اینکار می تونید از BackgroundWorker و یا روش delegate و Callback (که نمونه بحث مطرح شده در این زمینه رو می تونید اینجا ببینید.) استفاده کنید.
یعنی یه چیزی مثل کد زیر باید بنویسید و در نهایت هم SetItemComboBox_ThreadSafe رو استفاده کنید:
delegate void SetItemComboBoxCallback(ComboBox cbox);
private void SetItemComboBox(ComboBox cbox)
{
foreach (string item in ColorName)
{ cbox.Items.Add(item); }
}
private void SetItemComboBox_ThreadSafe();
{
foreach (ComboBox cb in cmb)
{
if (cb.InvokeRequired)
{
SetItemComboBoxCallback sicb = new SetItemComboBoxCallback(SetItemComboBox)
this.Invoke(sicb, new object[] { cb });
}
else
SetItemComboBox(cb)
}
}
پ.ن. : البته من ابن کد رو تو Notepad نوشتم و تست نکردم، خواستم کلیت مطلب رو برسونم!
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
نقل قول:
نوشته شده توسط
Saeed_m_Farid
فکر کنم من ده ها بار شاهد پرسیدن این مورد در فروم بودم!
شما نمی تونید از Thraed جداگانه (یعنی Thraed ای غیر از Thread اصلی فرم) با عناصر روی فرم کار کنید :
Thread-Safe Calls to Windows Forms Controls؛ برای اینکار می تونید از
BackgroundWorker و یا روش delegate و Callback (که نمونه بحث مطرح شده در این زمینه رو می تونید
اینجا ببینید.) استفاده کنید.
یعنی یه چیزی مثل کد زیر باید بنویسید و در نهایت هم SetItemComboBox_ThreadSafe رو استفاده کنید:
delegate void SetItemComboBoxCallback(ComboBox cbox);
private void SetItemComboBox(ComboBox cbox)
{
foreach (string item in ColorName)
{ cbox.Items.Add(item); }
}
private void SetItemComboBox_ThreadSafe();
{
foreach (ComboBox cb in cmb)
{
if (cb.InvokeRequired)
{
SetItemComboBoxCallback sicb = new SetItemComboBoxCallback(SetItemComboBox)
this.Invoke(sicb, new object[] { cb });
}
else
SetItemComboBox(cb)
}
}
پ.ن. : البته من ابن کد رو تو Notepad نوشتم و تست نکردم، خواستم کلیت مطلب رو برسونم!
دستت درد نکنه.
دقیقا درست فرمودید.
نقل قول: کار با Thread و خطا در هنگام اجرای Thread
نقل قول:
نوشته شده توسط
sinashahab
من میتدی هستم ولی یه چیزایی خونده بودم که باید از delegate استفاده کنی.
ولی یکی از دوستانم اینو بهم پیشنهاد داد که درست هم کار می کرد :
با تشکر
سینا شیری همدانی:بامزه:
:لبخند:
هرچند اطلاعات زیادی ندارم اما احتمال میدم کار اصولی نباشه!!
این دستور کار میکنه اما زمانی که واسه انجام تابع میبره بیش از زمانی هست که اصلا از نخ استفاده نکرده بودم.
یعنی فرم لود میشه براحتی، بعد چند لحظه جهت اعمال تغییرات زمان میبره.
در حالی که قبلا فرم لود نمیشد کمی مکث میکرد بعد با کل تغییرات لود میشد. من میخوام در یک لحظه همه این اتفاق ها بیفته.
متشکر