Most popular

วันพฤหัสบดีที่ 5 พฤษภาคม พ.ศ. 2554

จัดการ C# Multi-Threading GUI เพื่อการใช้งานจริง (PART II)

ต่อจากตอนที่แล้ว "นักพัฒนาระบบ: จัดการ C# Multi-Threading GUI เพื่อการใช้งานจริง (PART I)"
ผู้เขียนจะนำ Project เดิมมาทดสอบต่อ ด้วยการปรับเปลี่ยนการทำงานให้ซับซ้อนมากขึ้น
ซึ่งใน C# เองถึงแม้จะมีโครงสร้างเหมือน Java แต่หลายอย่างก็เป็นไปในแบบ C++ ยิ่งในเรื่อง Thread นั้น C# ไม่มีการ Implement Thread เป็น Class Thread แต่เป็นการประยุคใช้ delegate เสมือน Pointer ใน C++ นั่นเอง

ผู้เขียนจะประกาศส่วนของ Member Class ใหม่ดังนี้

//ประกาศ delegate Method เพื่อใช้ปุ่ม Start 
public delegate void StartClick(object sender, EventArgs e);
public StartClick start;

//ประกาศ delegate Method เพื่อใช้ปุ่ม Stop   
public delegate void StopClick(object sender, EventArgs e);
public StopClick stop;

private double round = 0; //รอบในการทำงาน
private int i = 0;  //ค่าในการวนลูป
private bool isrun=true;  //ค่ากำหนดการทำงานของลูป
private Thread t, x, h;  //Instance Thread ทั้งหมด

จากนั้นสร้าง delegate instance ที่ Constructor
public Form1()
{
     InitializeComponent();
     start = new StartClick(button1_Click);
     stop = new StopClick(button2_Click);
}

ปรับปรุง Method fillList เป็น
void fillList(object obj)
{
    Invoke((MethodInvoker)delegate
    {
         //แปลง Type Parameter ตัวแรกเป็น ListBox
         //คือ Control ListBox ที่จะทำงานด้วย
         ListBox lb = (ListBox)((object[])obj)[0];
        //แปลง Type Parameter ตัวแรกเป็น Int
        //ค่า Int นำไปกำหนดค่าให้ Thread หยุดรอ 
         int sleep = (int)((object[])obj)[1];
         while (isrun)
         {
            Application.DoEvents();
            i++;
            lb.Items.Add(i);
            lb.SelectedIndex = lb.Items.Count - 1;
            lb.Update();
            Thread.Sleep(sleep);
         }
     });
}

นำ Component Timer มาวาง และ Properties เป็น

พร้อมกับใส่ Code ใน Event Tick
private void timer1_Tick(object sender, EventArgs e)
{
     round++;
     this.listBox4.Items.Add(round.ToString());
     if (round == 50)
         stop(button2, e);
     else
     {

         double r = round / 3;
         if (double.TryParse(Convert.ToString(round), out r))
             start(button1, e);
         else
             stop(button2, e);
     }
}


Code การทำงานของ Timer คือให้ใส่ค่ารอบการทำงานของ Timer ให้กับ ListBox4  โดยหากการทำงานมีจำนวน 50 รอบแล้ว ให้หยุดการทำงานของ Thread ทั้งหมดทันที แต่ถ้ายังไม่ถึง 50 รอบ ให้ทำการเกลี่ยค่าให้กับ ListBox ทั้ง 3 ตัว

Method ต่อมาคือ StopThread
private void  StopThread()
{
     isrun = false;
     t.Abort();
     x.Abort();
     h.Abort();
     timer1.Enabled = false;
}


Code Event OnClick ในปุ่มทั้ง 2 ปุ่มคือปุ่ม Stop(button2) และ Start(button1) คือ

//ปุ่ม Start 
private void  button1_Click(object sender, EventArgs e)
{
    isrun = true;
    timer1.Enabled = true;
    t = new Thread(fillList);
    x = new Thread(fillList);
    h = new Thread(fillList);

    t.Start(new object[]{listBox1,10});
    x.Start(new object[]{listBox2,50});
    h.Start(new object[]{listBox3,80});
}
 
//ปุ่ม Stop 
private void button2_Click(object sender, EventArgs e)
{
     this.StopThread();
}

 ทดสอบรันโปรแกรมและกดปุ่ม Start ผลที่ไ;ด้คือ ListBox 4 จะมีค่าไม่เกิน 50 เนื่องจากได้กำหนดให้ Timer ทำงาน 50 รอบ และ ListBox อีก 3 ตัวจะได้รับการใส่ค่าโดยการเกลี่ยค่าจากตัวแปร i ที่เป็น Member ของ Class

ไม่มีความคิดเห็น:

แสดงความคิดเห็น