PDA

View Full Version : MultiThreading



soccer player
دوشنبه 19 دی 1384, 13:57 عصر
با سلام
من وقتی در حالت عادی بدون تغییر دادن هیچ کنترلی در یک Thread از MultiThreading استفاده می کنم مشکلی ندارم ولی وقتی در یکی از Thread ها روی یک کنترل کار می کنم برنامه Error میدهد به عنوان مثال در یکی از Thread ها در یک حلقه بی نهایت خاصیت text یک کنترل label .


public void test()
{
int a = 1;
DateTime dt = new DateTime();
while (a != 2)
{
a = 1;
dt = DateTime.Now;
label1.Text = dt.TimeOfDay.ToString();
this.Refresh();
}

}
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread thread1;
thread1 = new System.Threading.Thread(new System.Threading.ThreadStart(test));
thread1.Start();

System.Threading.Thread thread2;
thread2 = new System.Threading.Thread(new System.Threading.ThreadStart(test1));
thread2.Start();
}



__________________________________________________ _____________________

حامد

Mehdi Asgari
دوشنبه 19 دی 1384, 23:52 عصر
سلام
قبل از اینکه thread1 رو Start کنی ، باید خاصیت IsBackground اون رو true کنی.
(در غیر این صورت اگه در حین اجرای thread کاربر بخواد برنامه رو ببنده ، برنامه ظاهرا از دید کاربر پاک میشه ، ولی با نگاه به لیست process های سیستم می بینیم که هنوز در حال اجراست)
در ضمن به نظر می یاد Refresh کردن یک کنترل در یک حلقه ، چیز زایدیه !!!!!!!
Error رو هم بگو که چی بود.
راستی چرا از یه Timer استفاده نمی کنی ؟؟؟؟؟؟؟

soccer player
سه شنبه 20 دی 1384, 12:00 عصر
در ضمن به نظر می یاد Refresh کردن یک کنترل در یک حلقه ، چیز زایدیه !!!!!!!
Error رو هم بگو که چی بود.
راستی چرا از یه Timer استفاده نمی کنی ؟؟؟؟؟؟؟

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

Error هم که این برنامه می دهد این است :

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


__________________________________________________ ______________________

حامد

Mehdi Asgari
سه شنبه 20 دی 1384, 14:21 عصر
سلام
ببین اصولا مدل برنامه نویسی Windows Forms ، تک رشته ای (Single Threaded) هستش.
([STAThread] هم که قبل از متد Main می بینی ، همینه. متدهای Invoke و BeginInvoke و Get)
هر کنترل ویندوز فقط میتونه از داخل همون Thread ی که در اون ایجاد شده ، کنترل بشه.( البته از Thread های دیگه هم میشه ، اما چون کنترل های ویندوز فرم ، Thread-Safe نیستند ، امکان قاطی کردن هست)
ما چیکار می کنیم؟
مستقیما متد test رو به Thread مون نمیدیم ، بلکه Thread ما ، یک stub رو اجرا میکنه و این stub هستش که به طرز صحیح ، متد مثلا test رو فراخوانی می کنه.
به کد زیر یه نگاه بنداز:
(اینجا از همون متد test و اصولا همون مثال خودتون استفاده شده)


void stub()
{
if(label1.InvokeRequired)
label1.BeginInvoke(new MethodInvoker(test));
else
test();
}

private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread thread1;
thread1 = new System.Threading.Thread(new System.Threading.ThreadStart(test));
thread1.IsBackground = true;
thread1.Start();
}



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

anubis_ir
سه شنبه 20 دی 1384, 16:17 عصر
How can I update my user interface from a thread that did not create it?
http://blogs.msdn.com/csharpfaq/archive/2004/03/17/91685.aspx

Threading and UI
http://www.codeproject.com/csharp/ThreadingAndUI.asp