จากตอนที่แล้ว "ประยุคใช้ C# Threading แยก Process การทำงานของโปรแกรมแบบ GUI"
ตอนนี้ผู้เขียนจะอธิบายการใช้ Thread มากกว่า 1 Thread ในที่นี้ผู้เขียนไม่นับ Thread ของโปรแกรม GUI ที่ต้องมีอยู่แล้ว
ผู้เขียนได้เพิ่มการทำงานจากตัวอย่างที่แล้ว โดยให้ทำการเพิ่มข้อมูลใส่ใน ListBox หลายตัว โดยออกแบบฟอร์ม ดังนี้
บนฟอร์มจะมี ListBox ทั้งหมด 4 ตัวและมีปุ่ม Start 1 ปุ่มคือ Button1
จากนั้นผู้เขียนจะทำการดัดแปลง method fillList ให้มีความยืดหยุ่นสูง เพื่อสามารถใช้ทำงานได้โดยหลายๆ Thread
void fillList(object obj)
{
Invoke((MethodInvoker)delegate
{
int i = 0;
// Parameter ที่ส่งเข้ามาเป็นแบบ array ในที่นี้ให้ index ที่ 0 คือ Control ListBox
ListBox lb = (ListBox)((object[])obj)[0];
// Parameter ที่ส่งเข้ามาเป็นแบบ array ในที่นี้ให้ index ที่ 1 คือ ค่าสูงสุดที่ต้องการให้วนลูป
int max = (int)((object[])obj)[1];
while (true)
{
i++;
lb.Items.Add(i);
if (i == max)
break;
}
});
}
ที่ปุ่ม Start นั้นให้เรียกใช้ Thread 2 ตัว เพื่อใส่ค่าให้ LisBox1 และ ListBox2
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(fillList);
t.Start(new object[]{listBox1,DateTime.Now.Year+543}); //ส่ง Parameter ที่มีรูปแบบเป็น array
Thread x = new Thread(fillList);
x.Start(new object[] { listBox2, DateTime.Now.Year}); //ส่ง Parameter ที่มีรูปแบบเป็น array
}
จะเห็นว่าเมื่อทั้ง 2 Thread ทำงานกับ method fillList ก็จะมีการส่ง Parameter เป็น array ไปให้ด้วย
โดยที่มีการสร้าง object เป็น array แล้วส่งค่าไปในทันที
ผลที่ได้ก็คือ ListBox ทั้ง 2 ตัวจะทำงานพร้อมกัน โดยที่ ListBox1 จะถูกวนลูปตั้งแต่ 1 จนถึงปี พ.ศ. ปัจจุบัน ส่วน ListBox 2 จะถูกวนลูปตั้งแต่ 1 จนถึงปี ค.ศ. ปัจจุบัน ดังภาพ
การทำงานของทั้ง 2 Thread นั้นมีการทำงานคล้ายกัน และทำไปพร้อมๆกัน อย่างเป็นอิสระไม่รอกัน จึงไม่หน่วงการทำงานของฟอร์มซึ่งก็คืออีก Thread นั่นเอง
Multi - threading ทำงานตามลำดับ โดยใช้ join(timeout)
ใน Thread แต่ละตัวที่สร้างขึ้นจะมี method join เพื่อให้ใช้สำหรับบอกให้ thread ทำงานต่อเมื่อถึงเวลาของตน
โดยปกติ join ต้องการค่า Parameter เป็น เวลา timeout จะเป็น milliseconds หรือ Timespan ก็ได้ เพื่อหลังจากครบเวลาจะให้ Thread ทำงานได้
เพื่อให้เห็นการทำงานอย่างชัดเจน ผู้เขียนได้ลองปรับปรุงการแสดงผลของ method fillList ดังนี้
void fillList(object obj)
{
Invoke((MethodInvoker)delegate
{
int i = 0;
ListBox lb = (ListBox)((object[])obj)[0];
int max = (int)((object[])obj)[1];
while (true)
{
i++;
lb.Items.Add(i);
//เพิ่มส่วนนี้เข้าไปเพื่อให้เห็นการทำงานของ Thread กับ ListBox ได้ชัดเจน
lb.SelectedIndex = lb.Items.Count - 1;
lb.Update();
if (i == max)
break;
}
});
}
จากนั้นใช้ Thread ทั้งหมด 3 ตัวเพื่อเพิ่มข้อมูลให้กับ ListBox1 , ListBox2 และ ListBox3
โดยปรับปรุ่ง Code ที่ปุ่ม Start ดังนี้
Thread t = new Thread(fillList);
Thread x = new Thread(fillList);
Thread h = new Thread(fillList);
t.Start(new object[]{listBox1,5000});
t.Join(0); //ให้ Thread t เริ่มทำงานทันที
x.Start(new object[] { listBox2, 550});
x.Join(2000); //ให้ Thread x ทำงานภายใน 2 วินาที
h.Start(new object[] { listBox3, 3790 });
เมื่อกดปุ่ม Start
Thread t และ x จะทำงานตามคำสั่ง join ที่มีเวลา timeout เป็นตัวกำหนด จะได้ผลตามภาพด้านล่างนี้
Most popular
-
Trigger คืออะไร? ท่านที่เคยเขียนโปรแกรม และเคยใช้ Event handle ก็จะนึกถึงการทำงานของ Trigger ไม่ยาก Trigger ก็คือ Code คำสั่ง SQL ที่ถูกสร...
-
MySQL Workbench ที่ผู้เขียนใช้ทำตัวอย่างเป็น Version 5.2.34 CE สำหรับ Windows 32 bit หรือตัวใหม่กว่าก็ได้ครับ ดาวน์โหลดได้ที่นี่ http://www...
-
คนที่มีภาพใน facebook เยอะๆก็คงจะต้องการย้ายภาพไปมา บางทีก็เอาภาพบนกระดานเก็บลงอัลบั้ม บางทีก็หาไม่เจอว่าจะย้ายได้ยังไง การย้ายอัลบั้มไม่ยา...
-
Tier คำนี้เมื่อแปลออกมาจะแปลได้ว่า "ชั้น" Tier ในวงการ Software ก็มีความหมายคล้ายกัน สำหรับท่านที่ยังไม่เข้าใจขอแนะนำง่ายๆ โดยให้...
-
หลายท่านคงเคยเล่น หรือไม่ก็รู้จักชื่อเสียงเรียงนามของเกมนี้กันบ้าง หลังจากที่โด่งดังมาจากวงการ Tablet และ Smart Phone ก็ได้ออก Version ที่เล...
วันจันทร์ที่ 2 พฤษภาคม พ.ศ. 2554
จัดการ C# Multi-Threading GUI เพื่อการใช้งานจริง (PART I)
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)
มีวิธี ให้เทรด แต่ละตัวทำงานตามตัวอย่างแต่ ตัว ui ยังสามารถขยับได้ไหมครับ
ตอบลบถ้าหมายถึงการให้ event ต่างๆยังทำงานอยู่ในขณะที่วนลูป ก็มีอยู่ 2 วิธีครับ
ตอบลบคือ การใส่ Application.DoEvents(); ไว้ในลูป
หรือการใช้ Method Invoke ก้ได้ครับ