<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      線程與線程池以及任務和協商式取消

      一、線程

      使用System.Threading命名空間下的Thread類即可創建專有線程

      var t = new Thread(() => Console.WriteLine("new thread"));

      構造函數有如下四個版本

      Thread(ThreadStart start);

      public Thread(ThreadStart start, int maxStackSize);

      public Thread(ParameterizedThreadStart start);

      public Thread(ParameterizedThreadStart start, int maxStackSize)

      其中ThreadStart、ParameterizedThreadStart 是兩個委托類型,表示將要執行的函數,一個能接受參數,一個不接受參數。原型如下:

      public delegate void ParameterizedThreadStart(object obj);

      public delegate void ThreadStart();

      使用有參版本如下:

      var t = new Thread(state => Console.WriteLine($"My name is {state}"));
      t.Start("HK");

      調用Start如下的重載方法即可,內部會使用這個參數并調用相應的委托。

      public void Start(object parameter)

      一般來說,你將要執行的函數一般會將這個參數進行強制轉換,以便你使用。如下所示


      var t = new Thread(state =>
      {
           Point p = (state as Point) ?? throw new ArgumentException("無效的參數類型");//強制轉型
           Console.WriteLine($"The sum is {p.X + p.Y}");
      });

      t.Start(new Point(1,2));

      用到的類如下:

      public class Point
      {
           public int X { get; private set; }
           public int Y { get; private set; }
           public Point(int x, int y)
           {
               this.X = x;
               this.Y = y;
           }
      }

      函數體執行完之后,該線程就會被釋放,但是該創建該線程的實例對象的內存不會釋放,直到GC回收該內存。

      使用該類創建線程有明顯的一個缺點,不能使用有返回值的委托。并且線程不能重用,一經創建,執行完函數體之后,便被銷毀了,由于創建線程是有資源消耗的,對于客戶端程序可能不明顯,但對于高性能的服務端程序,頻繁的創建線程會浪費許多系統資源。所以要用下面要介紹的線程池。



      二、線程池

      顧名思義,就是存儲線程的一個池子,當有任務進來的時候,線程池分配一個線程去執行該任務,當該任務執行完之后,線程不會不銷毀,而是由線程池回收,待有新任務到來時,再去分配線程執行新任務。線程池中的線程只有第一次創建時才會損耗性能,創建完成之后,便不會了。

      同樣是在System.Threading命名空間下,使用ThreadPool靜態類如下的靜態方法即可

      public static bool QueueUserWorkItem(WaitCallback callBack, object state);

      public static bool QueueUserWorkItem(WaitCallback callBack);

      其中WaitCallback 也是一個委托類型,與ParameterizedThreadStart委托類型是一樣的

      public delegate void WaitCallback(object state);

      public delegate void ParameterizedThreadStart(object obj);


      注意與Thread類不同,使用QueueUserWorkItem方法之后,該任務會自動加入待執行列表,而不用像Thread類一樣顯示調用Start方法。注意不管是QueueUserWorkItem還是Start,執行之后函數體(任務)并不一定會馬上執行,而是等待調度,得到執行權之后才會執行。在系統資源不緊張的情況下,通常會立即執行。注意使用線程池創建的線程默認是后臺線程,使用Thread類創建的實例,默認是前臺線程,在Thread類的實例對象下,可以設置IsBackground屬性為false從而把線程設置為后臺線程。還可以通過Thread類的靜態對象Thread.CurrentThread來獲得當前線程實例對象,從而設置線程的前后臺屬性。前臺線程和后臺線程的區別見第三點。


      使用如下:

      ThreadPool.QueueUserWorkItem((state) =>
      {
           Console.WriteLine("new Task");
      });

      這會造成工作項進入一個待執行隊列,然后線程池會分配線程去執行這個工作項,線程池剛開始是空的,一但有工作項進來,就會創建線程去執行這個工作項,工作項完成之后,線程會由線程池回收復用,繼續去執行隊列中的工作項。當線程池中空閑的線程為0時,且待執行隊列還有工作項的時候,線程池會創建新的線程(如果系統資源足夠的話,否則只能等待有空閑的線程去執行隊列中的工作項)去執行這個工作項。

      然而線程返回值還是不能直接得到,要想直接得到返回值,可以通過System.Threading.Tasks命名空間下的Task<T>類。

      三、前臺線程和后臺線程以及協商式取消

      在CLR中,線程要么是前臺線程,要么是后臺線程,每個應用程序至少有一個前臺線程,所有前臺線程停止運行后,CLR將強制終止仍在運行的后臺線程。

      如下所示:

      static void Main(string[] args)
      {
           var t = new Thread(() =>
           {
               Thread.Sleep(1000);
               Console.WriteLine("Background Thread");
           });
           t.IsBackground = true;//設置為后臺線程
           t.Start();
           Console.WriteLine("Main thread over");
      }

      image

      設置t.IsBackground = false

      image

      有時我們想讓執行的工作取消,可以使用協商式取消的方式,為什么叫協商式,是因為要雙方都要遵守一個約定。我們使用System.Threading命名空間下的CancellationTokenSource類。然后我們可以通過該類實例下的Token屬性獲得一個值類型實例,這個值類型是CancellationToken,同樣是在System.Threading命名空間下。雙方使用這個實例便可實現協作式取消操作。如下所示:

      private static void OP(int n,CancellationToken token)
      {
           Thread.CurrentThread.IsBackground = false;
           int sum = 0;
           for (int i = 0; i < n; i++)
           {
               if(token.IsCancellationRequested)//如果是通過Task執行的,這里應該拋出一個異常(token.ThrowIfCancellationRequested),因為任務可以有返回值,如果像這里一樣處理,則無法知道該任務是正常結束了還是取消了。
               {                                               //另外注意,通過Thread類的實例或者是使用ThreadPool創建的線程是無法在調用線程直接捕獲異常然后進行處理的,所以這里不可以選擇拋出異常,一旦拋出異常則應用程序就會終止。
                   Console.WriteLine("work is not over");
                   Console.WriteLine(sum.ToString());
                   return;
               }
               sum += i;
               Thread.Sleep(100);
           }
           Console.WriteLine("work is over");
           Console.WriteLine(sum.ToString());
      }
      static void Main(string[] args)
      {
           var cts = new CancellationTokenSource();
           ThreadPool.QueueUserWorkItem((statue) => OP(10,cts.Token));
           Console.ReadLine();
           cts.Cancel();
      }

      提前按下回車鍵

      image

      正常完成

      image

      posted @ 2019-12-25 22:28  白煙染黑墨  閱讀(501)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 丁香五月亚洲综合在线国内自拍| 人妻系列中文字幕精品| 人妻精品动漫h无码| 不卡一区二区国产在线| 女同AV在线播放| 舞阳县| 久久月本道色综合久久| 精品久久久久久无码不卡| 免费可以在线看a∨网站| 亚洲成年av天堂动漫网站| 亚洲熟妇在线视频观看| 国产av不卡一区二区| 精品国产亚洲一区二区三区在线观看| 日本丰满老妇bbb| 在线看国产精品自拍内射| 国产一区二区三区精品综合| 亚洲色婷婷综合开心网| 精品在免费线中文字幕久久| 精品中文人妻在线不卡| 亚洲天堂一区二区成人在线| 亚洲男人天堂东京热加勒比| 欧美老熟妇乱子伦牲交视频| 欧美黑人巨大xxxxx| 久久99国产精品尤物| h动态图男女啪啪27报gif| 欧美丰满熟妇xxxx性| 日韩av裸体在线播放| 国产一区二区三区四区五区加勒比| 婷婷开心深爱五月天播播| 福利一区二区在线播放| 亚洲天堂在线观看完整版| 小鲜肉自慰网站xnxx| 第一精品福利导福航| 91亚洲免费视频| 久热这里只有精品12| 18黑白丝水手服自慰喷水网站 | 不卡无码人妻一区三区音频| 国产精品99久久免费| 丝袜美腿视频一区二区三区| 久久精品人妻无码一区二区三区| 久久av色欲av久久蜜桃网|