C#Thread學習


一.Thread的使用方式

1.不帶參數

(1)使用lambda

        public static void fun1()
        {
            Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
            new Thread(new ThreadStart(() =>
            {
                Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
            })).Start();
        }

  

(2)使用方法

        public static void ConsoleString()
        {
            Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
        }

        public static void fun2()
        {
            Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
            new Thread(new ThreadStart(ConsoleString)).Start();
        }

  

2.帶參數(只允許帶一個object類型參數)

        public static void fun3()
        {
            Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
            new Thread(new ParameterizedThreadStart(t =>
            {
                Console.WriteLine($"{t} Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
            })).Start("haha");
        }

  

3.等待線程執行

        public static void fun4()
        {
            Console.WriteLine($"Main start ThreadId:{Thread.CurrentThread.ManagedThreadId}");
            Thread t = new Thread(new ThreadStart(() =>
             {
                 Thread.Sleep(1000);
                 Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
             }));
            t.Start();
            t.Join();
            Console.WriteLine($"Main end ThreadId:{Thread.CurrentThread.ManagedThreadId}");
        }

  執行結果:

 

4.結束線程

Abort();

 二.IsBackground講解

thread.IsBackground=true:該線程為后台線程

thread.IsBackground=true:該線程為前台線程,Thread默認為前台線程

1.前台線程和后台線程的區別

  Net的公用語言運行時(Common Language Runtime,CLR)能區分兩種不同類型的線程:前台線程和后台線程。這兩者的區別就是:應用程序必須運行完所有的前台線程才可以退出;而對於后台線程,應用程序則可以不考慮其是否已經運行完畢而直接退出,所有的后台線程在應用程序退出時都會自動結束。

原理:只要所有前台線程都終止后,CLR就會對每一個活在的后台線程調用Abort()來徹底終止應用程序

2.使用建議

  對於一些在后台運行的線程,當程序結束時這些線程沒有必要繼續運行了,那么這些線程就應該設置為后台線程。比如一個程序啟動了一個進行大量運算的線程,可是只要程序一旦結束,那個線程就失去了繼續存在的意義,那么那個線程就該是作為后台線程的。而對於一些服務於用戶界面的線程往往是要設置為前台線程的,因為即使程序的主線程結束了,其他的用戶界面的線程很可能要繼續存在來顯示相關的信息,所以不能立即終止它們。這里我只是給出了一些原則,具體到實際的運用往往需要編程者的進一步仔細斟酌。
  一般后台線程用於處理時間較短的任務,如在一個Web服務器中可以利用后台線程來處理客戶端發過來的請求信息。而前台線程一般用於處理需要長時間等待的任務,如在Web服務器中的監聽客戶端請求的程序,或是定時對某些系統資源進行掃描的程序。

3.示例

        public static void fun5()
        {
            Thread t1 = new Thread(new ThreadStart(() =>
            {
                for (int i = 0; i < 50; i++)
                {
                    Thread.Sleep(100);
                    Console.WriteLine($"Thread1 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
                }
            }));
            t1.Start();

            Thread t2 = new Thread(new ThreadStart(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(100);
                    Console.WriteLine($"Thread2 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
                }
            }));
            t2.IsBackground = true;
            t2.Start();
        }

  運行結果:

當t1執行完后,t2也不在執行,說明t1執行完成后,進程結束。

4.結束進程方式關聯

private void fun()
        {
            Thread t1 = new Thread(new ThreadStart(() =>
            {
                for (int i = 0; i < 50; i++)
                {
                    Thread.Sleep(1000);
                    Debug.WriteLine($"Thread1 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
                }
            }));
            t1.Start();

            Thread t2 = new Thread(new ThreadStart(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    Thread.Sleep(1000);
                    Debug.WriteLine($"Thread2 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
                }
            }));
            t2.IsBackground = true;
            t2.Start();
        }

  

(1)winform中:Application.Exit():所有線程都結束后(前台線程都結束后,后台線程自動結束),然后進程結束

執行 Application.Exit()

結果:等待t1執行完后,t2也不在執行,然后結束進程。

(2)Environment.Exit(0):不等待線程結束,直接結束進程

執行 Environment.Exit(0)

結果:直接結束進程,不等待線程。

 

 

參考:

https://blog.csdn.net/Fenglele_Fans/article/details/78555895

https://www.cnblogs.com/Again/articles/7085596.html

 


免責聲明!

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



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