c# 線程的基本使用


創建線程

線程的基本操作

線程和其它常見的類一樣,有着很多屬性和方法,參考下表:

創建線程的方法有很多種,這里我們先從thread開始創建線程

  class Program
    {
        static void Main(string[] args)
        {
            Thread t = new Thread(PrintNumbers);
            t.Start();
            PrintNumbers();
        }

        static void PrintNumbers()
        {
            Console.WriteLine("Starting...");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i);
            }
        }
    }

Thread構造函數接受兩種委托

    public delegate void ThreadStart(); 無返回值、無參的

    public delegate void ParameterizedThreadStart(object obj);無返回值、參數為object類型的方法

既然構造函數是委托那么我還可以用lambda來簡寫

  Thread t = new Thread(()=> {
                Console.WriteLine("Starting...");
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine(i);
                }
            });
            t.Start();

很多時候我們都需要線程執行的是一個有參的方法,下面看看如何調用有多個參數的方法,

        static void Main(string[] args)
        {
            int b = 10;
            string c = "主線程";
            Thread t = new Thread(()=> PrintNumbers(b,c));

            t.Start();

        }
        static void PrintNumbers(int count,string name)
        {
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine("name:{0},i:{1}",name,i);
            }
        }

Thread.Join()

我的理解是當調用Join()方法時主線程會停止工作,我不干活了,等你干完了我在繼續干活如:


    static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "主線程";
            Console.WriteLine("線程名字:{0},線程工作狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
            Thread abortThread = new Thread(AbortMethod);
            abortThread.Name = "子線程";
            abortThread.Start();
            abortThread.Join();

            Console.WriteLine("線程名字:{0},子線程工作狀態:{1}", abortThread.Name, abortThread.ThreadState);
            Console.WriteLine("繼續干活");

            Console.Read();

        }
        private static void AbortMethod()
        {
            Console.WriteLine("線程名字:{0},子線程工作狀態:{1}",Thread.CurrentThread.Name,Thread.CurrentThread.ThreadState);
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine(i);
            }

        }
//輸出結果

線程名字:主線程,線程工作狀態:Running
線程名字:子線程,子線程工作狀態:Running
0
1
2
3
4
線程名字:子線程,子線程工作狀態:Stopped
繼續干活

Thread.Abort()

Abort()方法來終止線程的運行,我們在使用它的時候要主要,它是通過拋出ThreadAbortException異常的方式來終止線程的

      static void Main(string[] args)
        {
            Thread abortThread = new Thread(AbortMethod);
            abortThread.Name = "test";
            abortThread.Start();
            Thread.Sleep(3000);
            try
            {
                abortThread.Abort();
            }
            catch(Exception e)
            {

                Console.WriteLine("主線程:{0}", Thread.CurrentThread.Name);
            }

            Console.WriteLine("我被開除了,子線程:{0},子線程狀態:{1}", abortThread.Name, abortThread.ThreadState);

            Console.Read();

        }
        private static void AbortMethod()
        {
            try
            {
                Console.WriteLine("子線程:{0},子線程狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
                Console.WriteLine("開始干活");
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine(i);
                }
                Console.WriteLine("繼續干活");
            }
            catch (Exception e)
            {
                Console.WriteLine("類型:"+e.GetType().Name);
                Console.WriteLine("子線程:{0},子線程狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
            }

        }
輸出
子線程:test,子線程狀態:Running
開始干活
0
1
類型:ThreadAbortException
子線程:test,子線程狀態:AbortRequested
我被開除了,子線程:test,子線程狀態:Aborted

從運行結果可以看出,調用Abort方法的線程引發的異常類型為ThreadAbortException, 以及異常只會在 調用Abort方法的線程中發生,而不會在主線程中拋出,並且調用Abort方法后線程的狀態不是立即改變為Aborted狀態,而是從AbortRequested->Aborted。

Thread.ResetAbort()

Abort方法可以通過跑出ThreadAbortException異常中止線程,而使用ResetAbort方法可以取消中止線程的操作,下面通過代碼演示使用 ResetAbort方法

      static void Main(string[] args)
        {
            Thread abortThread = new Thread(AbortMethod);
            abortThread.Name = "test";
            abortThread.Start();
            Thread.Sleep(1000);

            try
            {
                abortThread.Abort();

            }
            catch(Exception e)
            {

                Console.WriteLine("主線程:{0}", Thread.CurrentThread.Name);
            }

            Console.WriteLine("我被開除了,子線程:{0},子線程狀態:{1}", abortThread.Name, abortThread.ThreadState);

            Console.Read();

        }
        private static void AbortMethod()
        {
            try
            {
                Console.WriteLine("我要被開除了");

                for (int i = 0; i < 5; i++)
                {

                        Thread.Sleep(1000);
                        Console.WriteLine(i);

                }

            }
            catch (Exception e)
            {
                Thread.ResetAbort();
                Console.WriteLine("類型:"+e.GetType().Name);
                Console.WriteLine("子線程:{0},子線程狀態:{1}", Thread.CurrentThread.Name, Thread.CurrentThread.ThreadState);
            }
            Console.WriteLine("我又回來繼續干活");
        }

輸出
我要被開除了
我被開除了,子線程:test,子線程狀態:AbortRequested
類型:ThreadAbortException
子線程:test,子線程狀態:Running
我又回來繼續干活

線程的優先級

如果在應用程序中有多個線程在運行,但一些線程比另一些線程重要,這種情況下可以在一個進程中為不同的線程指定不同的優先級。線程的優先級可以通過Thread類Priority屬性設置,Priority屬性是一個ThreadPriority型枚舉,列舉了5個優先等級:AboveNormal、BelowNormal、Highest、Lowest、Normal。公共語言運行庫默認是Normal類型的。見下圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM