本文參考yc421206-[C#.NET] 如何 使用 多執行緒 Thread / 跨執行緒 存取UI
本文參考catyku-C# Thread應用

前置動作:

using System.Threading;

 

Thread三步驟:

1.建立ThreadStart委派
ThreadStart myRun = new ThreadStart(RunSample01);

2.建立Thread類別
Thread myThread = new Thread(myRun);

步驟1.2可以合併為:
Thread myThread = new Thread(new ThreadStart(RunSample01));

3.啟動執行緒
myThread.Start();

 

將Thread設定為背景執行緒:

myThread.IsBackground = true;

我在寫無窮回圈時,發現按[X]關閉Form,迴圈還是在背景執行,所以到MSDN找到下面的解決方法。

來自MSDN的說明:
執行緒不是背景執行緒就是前景執行緒。
背景執行緒和前景執行緒相同,唯一差別在於背景執行緒不會防止處理序終止。
一旦終止屬於處理序的所有前景執行緒之後,Common Language Runtime 就會結束處理序。
剩下的所有背景執行緒則會在尚未完成之前全部停止。

故解決方法就是,將thread設定為背景執行緒。(如果設定為false,按[X]關閉Form,執行緒仍在背景繼續執行,故要設定為true)

 

Thread宣告:

public Thread thread1;

可以將thread宣告成Global變數,但是不能在此處new thread,要在function內new thread。

 

傳值的範例:

private void function() {
    threadClass1 obj = new threadClass1("thread1", 10);
    thread1 = new Thread(obj.runMe);
    thread1.IsBackground = true;
    thread1.Start();
}

class要跟form class在同一層

class threadClass1
{
    private String title;
    private int i;
    public thread1(String title, int i)
    {
        this.title = title;
        this.i = i;
    }
    public void runMe()
    {
        Console.Write(title + ":開始 \r\n");
        System.Threading.Thread.Sleep(1000);
        for (int i = 0; i < this.i; i++)
        {
            Console.Write(title + "\r\n");
            System.Threading.Thread.Sleep(2000);
        }
        Console.Write(title + ":結束 \r\n");
        System.Threading.Thread.Sleep(1000);
    }
}

 

用上面的code隨筆寫了一個範例:
按Button時會new thread執行process,thread還沒執行完畢,不允許再new

public Boolean flag=false;

private void button_Click(object sender, EventArgs e)
{
    if (flag == false)
    {
        function();
        flag = true;
        return;
    }

    if (thread1.IsAlive) //如果thread 還存在(還沒執行完畢)
    {
        Console.Write("thread:還沒結束 \r\n");
        System.Threading.Thread.Sleep(1000);
    }
    else
    {
        function();
    }
}

 

//完整範例Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Thread t1,t2,t3;
        public Boolean flag=false;

        public Form1()
        {
            InitializeComponent();
        }

        private void RunSample01()
        {
            Console.WriteLine("建立了一個執行緒{0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
        }

        private void RunSample02()
        {
            for (int i=0;;i++)
            {
                Console.WriteLine("執行緒{0}: 迴圈第{1}次執行", Thread.CurrentThread.ManagedThreadId, i+1);
                Thread.Sleep(500);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //1.建立ThreadStart委派
            //ThreadStart myRun = new ThreadStart(RunSample01);
            //2.建立Thread 類別
            //Thread myThread = new Thread(myRun);
            //上述兩句可合併
            Thread myThread = new Thread(new ThreadStart(RunSample01));
            //3.啟動執行緒
            myThread.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //1.建立ThreadStart委派
            ThreadStart myRun = new ThreadStart(RunSample02);
            try
            {
                //2.建立Thread 類別
                Thread myThread = new Thread(myRun);
                /* 執行緒不是背景執行緒就是前景執行緒。
                 * 背景執行緒和前景執行緒相同,唯一差別在於背景執行緒不會防止處理序終止。
                 * 一旦終止屬於處理序的所有前景執行緒之後,Common Language Runtime 就會結束處理序。
                 * 剩下的所有背景執行緒則會在尚未完成之前全部停止。
                 */
                //設定為背景執行緒(如果設定為false,按[X]關閉Form,執行緒仍在背景繼續執行,故要設定為true。)
                myThread.IsBackground = true;
                //3.啟動執行緒
                myThread.Start();
            }
            catch (Exception)
            {
                //例外
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            thread1 obj = new thread1(textBox1.Text,10);
            Thread t = new Thread(obj.runMe);
            t.IsBackground = true;
            t.Start();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            thread1 obj = new thread1("擦窗戶",10);
            t1 = new Thread(obj.runMe);
            t1.IsBackground = true;
            t1.Start();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            thread1 obj = new thread1("掃地",10);
            t2 = new Thread(obj.runMe);
            t2.IsBackground = true;
            t2.Start();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                if (t2.IsAlive) //如果thread t2 還存在(還沒執行完畢)
                {
                    Console.Write("掃地還沒結束不能拖地\r\n");
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    thread1 obj = new thread1("拖地", 10);
                    t3 = new Thread(obj.runMe);
                    t3.IsBackground = true;
                    t3.Start();
                }
            }
            catch (Exception)
            {
                MessageBox.Show("應該還沒掃地,所以出現錯誤!");
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (flag == false)
            {
                fun();
                flag = true;
                return;
            }

            if (t3.IsAlive) //如果thread 還存在(還沒執行完畢)
            {
                Console.Write("thread:還沒結束 \r\n");
                System.Threading.Thread.Sleep(1000);
            }
            else
            {
                fun();
            }
        }
        
        private void fun()
        {
            thread1 obj = new thread1("thread", 10);
            t3 = new Thread(obj.runMe);
            t3.IsBackground = true;
            t3.Start();
        }
    }

    class thread1
    {
        private String title;
        private int i;
        public thread1(String title, int i)
        {
            this.title = title;
            this.i = i;
        }
        public void runMe()
        {
            Console.Write(title + ":開始 \r\n");
            System.Threading.Thread.Sleep(1000);
            for (int i = 0; i < this.i; i++)
            {
                Console.Write(title + "\r\n");
                System.Threading.Thread.Sleep(2000);
            } 
            Console.Write(title + ":結束 \r\n");
            System.Threading.Thread.Sleep(1000);
        }
    }

}

arrow
arrow
    文章標籤
    c#
    全站熱搜

    伊 發表在 痞客邦 留言(0) 人氣()