2014年1月2日 星期四

C# Thread 多執行緒

早期的程式,在還沒有執行緒(thread)這個概念的時候,一件工作做完才接著做下一件;呼叫某個函式時,必須等該函式執行完畢,返回之後,呼叫端才能繼續下去。
Windows 作業系統有了處理序(process;又譯作「處理程序」或「行程」)的概念,作為隔離應用程式的基本單位。當使用者開啟某應用程式,作業系統會將它載入記憶體並開始執行,這個載入記憶體中運行的應用程式實體(instance),便稱為處理序。一個處理序會在系統中佔據一個記憶區塊,此區塊是個獨立的虛擬位址空間,其中包含該應用程式的程式碼以及相關資源,而且此空間只有該應用程式實體能夠存取,與別的執行互不相干。如此一來,運行中的各個處理序就不至於互相干擾,不會因為某個應用程式進入無窮迴圈而導致其他應用程式掛掉;同時,由於這些應用程式的處理序也被隔離於作業系統的核心程式碼之外,作業系統本身也更加穩固。

現在很多的程式語言都有支援多執行緒,C#當然也不例外,多執行緒在網路程式設計當中具有相當重要的用途,幾乎所有網路程式都會依賴多執行緒去處理對方的連線。

下面例子我建了兩個執行緒而不會相互影響的執行緒,第一個線程是主線程,它顯示了'Thread:A'消息,第二個線程是ThreadB 'Thread:B'消息。



using System.Threading;

namespace ThreadTest
{
    class Program
    {

        static void Main(string[] args)
        {
            Thread t = new Thread(TB);
            Console.WriteLine("多執行緒啟動 :");
            t.Start();

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("多執行緒 : A");
            }

            Console.WriteLine("多執行緒完成");
            Console.ReadKey();
        }

        public static void TB()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Thread : B");
            }
        }
    }
}

接下來比較進階的寫法,使用能協助ThreadStart的Delegate創建執行緒
在建立管理式的線程時,在執行緒中中執行的方法由ThreadStart委託表示並傳遞給Thread建構函數。 那就是ThreadStart委託代表一個在線程執行中使用的方法。

讓我們看看在ThreadStart委託的協助下創建執行緒的方式:
namespace ParameterizedThread
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t = new Thread(new ThreadStart(Method));
            t.Name = "2";
            t.Start();
            for (inti = 0; i < 20; i++)
            {
                Console.WriteLine("1");
            }
            Console.WriteLine("結束...");
            Console.ReadKey();
        }
        public static void Method()
        {

            for (inti = 0; i < 10; i++)
            {
                Console.WriteLine("2");
            }

        }
    }
}


再來是使用參數或參數化線程建立執行緒。
我們還可以建立參數化執行緒來建立參數化線程:

using System.Threading;

namespace ParameterizedThread
{
    class Program
    {
        static voidMain(string[] args)
        {
            ParameterizedThreadStart paraThread = new ParameterizedThreadStart(Method);
            Thread t = new Thread(paraThread);
            t.Name = "2";
            Console.WriteLine("開始...");
            t.Start(th.Name);

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("1");
            }
            Console.WriteLine("結束...");
            Console.ReadKey();
        }
        public static void Method(object obj)
        {
            string name = Convert.ToString(obj);
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(name);
            }

        }
    }
}

執行緒Priority機制:
執行緒Priority機制是指定線程的調度優先級,線程的執行基於其優先級執行。 當我們創建任何線程而不分配其優先級時,默認情況下將為其分配正常優先級。 線程優先級不會影響線程的狀態。

namespace ForegroundThread
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread tA = new Thread(new ThreadStart(ChildTA));
            Thread tB = new Thread(new ThreadStart(ChildTB));

            tA.Name = "線程 A";
            tB.Name = "線程 B";
            tB.Priority = ThreadPriority.Highest;
            tA.Start();
            tB.Start();
            Thread.CurrentThread.Name = "Main";

            for (inti = 0; i < 20; i++)
            {
                Console.WriteLine(Thread.CurrentThread.Name);
            }

            Console.ReadKey();
        }
        public static void ChildTA()
        {
            for (inti = 0; i < 10; i++)
            {
                Console.WriteLine("子執行緒 A:");
            }
        }
        public static void ChildTB()
        {
            for (inti = 0; i < 10; i++)
            {
                Console.WriteLine("子執行緒 B:");
            }
        }
    }
}


上面是一些比較基本的用法,不過非不得已,有時候能不用多執行緒的話就不要用,因為在維護有除錯上的難度,使用前請詳細閱讀風險說明書。

-雲遊山水為知已逍遙一生而忘齡- 電腦神手

沒有留言:

張貼留言