乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      .NET異步和多線(xiàn)程系列(二)- Thread和ThreadPool

       新進(jìn)小設(shè)計(jì) 2021-03-19

      一、Thread類(lèi)

      C#里面的多線(xiàn)程:Thread類(lèi)是C#語(yǔ)言對(duì)線(xiàn)程對(duì)象的一個(gè)封裝。

      首先看下如何開(kāi)啟線(xiàn)程,執(zhí)行委托的內(nèi)容:

      /// <summary>/// 一個(gè)比較耗時(shí)耗資源的私有方法/// </summary>private void DoSomethingLong(string name)
      {
          Console.WriteLine($"****************DoSomethingLong Start  {name}  {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +$"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");long lResult = 0;for (int i = 0; i < 1_000_000_000; i++)
          {
              lResult += i;
          }
          Thread.Sleep(2000);
          Console.WriteLine($"****************DoSomethingLong   End  {name}  {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +$"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************");
      }
      /// <summary>/// 多線(xiàn)程 Thread類(lèi)是.NET Framework 1.0的時(shí)候出現(xiàn)的/// Thread:C#對(duì)線(xiàn)程對(duì)象的一個(gè)封裝/// </summary>private void btnThread_Click(object sender, EventArgs e)
      {
          Console.WriteLine($"****************btnThread_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +$"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
      
          {
              ParameterizedThreadStart method = o => this.DoSomethingLong("btnThread_Click");
              Thread thread = new Thread(method);
              thread.Start("浪子天涯");//開(kāi)啟線(xiàn)程,執(zhí)行委托的內(nèi)容    }
      
          Console.WriteLine($"****************btnThread_Click End   {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +$"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
      }

      線(xiàn)程等待、線(xiàn)程優(yōu)先級(jí)、前臺(tái)線(xiàn)程和后臺(tái)線(xiàn)程:

      {
          ThreadStart method = () =>{
              Thread.Sleep(5000);this.DoSomethingLong("btnThread_Click");
              Thread.Sleep(5000);
          };
          Thread thread = new Thread(method);
          thread.Start(); //開(kāi)啟線(xiàn)程,執(zhí)行委托的內(nèi)容//該花括號(hào)內(nèi)的這些方法已經(jīng)被微軟拋棄了,建議不要去用    {//thread.Suspend(); //暫停//thread.Resume();//恢復(fù)    真的不該要的,暫停不一定馬上暫停;讓線(xiàn)程操作太復(fù)雜了//thread.Abort();//線(xiàn)程是計(jì)算機(jī)資源,程序想停下線(xiàn)程,只能向操作系統(tǒng)通知(線(xiàn)程拋異常),//會(huì)有延時(shí)/不一定能真的停下來(lái)//Thread.ResetAbort();    }//1等待while (thread.ThreadState != ThreadState.Stopped)
          {
              Thread.Sleep(200); //當(dāng)前線(xiàn)程休息200ms    }//2 Join等待thread.Join(); //運(yùn)行這句代碼的線(xiàn)程,等待thread的完成thread.Join(1000); //最多等待1000msConsole.WriteLine("這里是線(xiàn)程執(zhí)行完之后才操作。。。");//最高優(yōu)先級(jí):優(yōu)先執(zhí)行,但不代表優(yōu)先完成看,甚至說(shuō)極端情況下,還有意外發(fā)生,不能通過(guò)這個(gè)來(lái)控制線(xiàn)程的執(zhí)行先后順序thread.Priority = ThreadPriority.Highest;//是否是后臺(tái)線(xiàn)程 默認(rèn)是falsethread.IsBackground = false; //默認(rèn)是false 前臺(tái)線(xiàn)程,進(jìn)程關(guān)閉,線(xiàn)程需要計(jì)算完后才退出//thread.IsBackground = true;//關(guān)閉進(jìn)程,線(xiàn)程退出}

      下面來(lái)看下Thread類(lèi)的使用:

      基于Thread封裝一個(gè)帶有回調(diào)的

      /// <summary>/// 基于Thread封裝一個(gè)回調(diào)/// 回調(diào):?jiǎn)?dòng)子線(xiàn)程執(zhí)行動(dòng)作A--不阻塞--A執(zhí)行完后子線(xiàn)程會(huì)執(zhí)行動(dòng)作B/// </summary>/// <param name="threadStart">多線(xiàn)程執(zhí)行的操作</param>/// <param name="actionCallback">線(xiàn)程完成后,回調(diào)的動(dòng)作</param>private void ThreadWithCallBack(ThreadStart threadStart, Action actionCallback)
      {//Thread thread = new Thread(threadStart);//thread.Start();//thread.Join(); //錯(cuò)了,因?yàn)榉椒ū蛔枞?/actionCallback.Invoke();ThreadStart method = new ThreadStart(() =>{
              threadStart.Invoke();
              actionCallback.Invoke();
          });new Thread(method).Start();
      }
      {
          ThreadStart threadStart = () => this.DoSomethingLong("btnThread_Click");
          Action actionCallBack = () =>{
              Thread.Sleep(2000);
              Console.WriteLine($"This is Calllback {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
          };this.ThreadWithCallBack(threadStart, actionCallBack);
      }

      基于Thread封裝一個(gè)帶有返回值的

      /// <summary>/// 基于Thread封裝一個(gè)帶有返回值的/// 1 異步,非阻塞的/// 2 還能獲取到最終計(jì)算結(jié)果/// /// 既要不阻塞,又要計(jì)算結(jié)果?不可能!故此處返回一個(gè)委托,當(dāng)外部需要使用結(jié)果的時(shí)候再阻塞,此時(shí)可能已經(jīng)計(jì)算完了。/// </summary>private Func<T> ThreadWithReturn<T>(Func<T> func)
      {
          T t = default(T);
          ThreadStart threadStart = new ThreadStart(() =>{
              t = func.Invoke();
          });
          Thread thread = new Thread(threadStart);
          thread.Start();return new Func<T>(() =>{
              thread.Join();//thread.ThreadStatereturn t;
          });
      }
      {
          Func<int> func = () =>{
              Thread.Sleep(5000);return DateTime.Now.Year;
          };
          Func<int> funcThread = this.ThreadWithReturn(func);//非阻塞Console.WriteLine("do something 1");
          Console.WriteLine("do something 2");
          Console.WriteLine("do something 3");int iResult = funcThread.Invoke();//阻塞}

      控制線(xiàn)程的數(shù)量(僅供參考):

      {
          List<Thread> threads = new List<Thread>();for (int i = 0; i < 100; i++)
          {if (threads.Count(t => t.ThreadState == ThreadState.Running) < 10)
              {
                  Thread thread = new Thread(new ThreadStart(() => { }));
                  thread.Start();
                  threads.Add(thread);
              }else{
                  Thread.Sleep(200);
              }
          }
      }

      二、ThreadPool類(lèi)

      由于Thread類(lèi)功能繁多,反而用不好--就像給4歲小孩一把熱武器,反而會(huì)造成更大的傷害。而且對(duì)線(xiàn)程數(shù)量也是沒(méi)有管控的。故微軟在.NET Framework 2.0推出來(lái)ThreadPool線(xiàn)程池。

      如果某個(gè)對(duì)象創(chuàng)建和銷(xiāo)毀代價(jià)比較高,同時(shí)這個(gè)對(duì)象還可以反復(fù)使用的,就需要一個(gè)池子。

      保存多個(gè)這樣的對(duì)象,需要用的時(shí)候從池子里面獲??;用完之后不用銷(xiāo)毀,放回池子;(享元模式)

      節(jié)約資源提升性能;此外,還能管控總數(shù)量,防止濫用;

      ThreadPool的線(xiàn)程都是后臺(tái)線(xiàn)程。

      下面我們直接來(lái)看下相關(guān)代碼:

      /// <summary>/// ThreadPool線(xiàn)程池/// 由于Thread類(lèi)功能繁多,反而用不好--就像給4歲小孩一把熱武器,反而會(huì)造成更大的傷害/// 對(duì)線(xiàn)程數(shù)量是沒(méi)有管控的/// /// 線(xiàn)程池是.NET Framework 2.0推出來(lái)的/// 如果某個(gè)對(duì)象創(chuàng)建和銷(xiāo)毀代價(jià)比較高,同時(shí)這個(gè)對(duì)象還可以反復(fù)使用的,就需要一個(gè)池子/// 保存多個(gè)這樣的對(duì)象,需要用的時(shí)候從池子里面獲取;用完之后不用銷(xiāo)毀,放回池子;(享元模式)/// 節(jié)約資源提升性能;此外,還能管控總數(shù)量,防止濫用;/// /// ThreadPool的線(xiàn)程都是后臺(tái)線(xiàn)程/// /// 大家課后可以試試,基于ThreadPool去封裝回調(diào)--返回值的/// </summary>private void btnThreadPool_Click(object sender, EventArgs e)
      {
          Console.WriteLine($"****************btnThreadPool_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +$"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");//啟動(dòng)線(xiàn)程    {
              ThreadPool.QueueUserWorkItem(o => this.DoSomethingLong("btnThreadPool_Click1"));
              ThreadPool.QueueUserWorkItem(o => this.DoSomethingLong("btnThreadPool_Click2"), "浪子天涯");
          }
      
          {
              ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
              Console.WriteLine($"當(dāng)前電腦最大workerThreads={workerThreads} 最大completionPortThreads={completionPortThreads}");
      
              ThreadPool.GetMinThreads(out int workerThreadsMin, out int completionPortThreadsMin);
              Console.WriteLine($"當(dāng)前電腦最小workerThreads={workerThreadsMin} 最大completionPortThreads={completionPortThreadsMin}");//設(shè)置的線(xiàn)程池?cái)?shù)量是進(jìn)程全局的(慎用,一般不用)//委托異步調(diào)用--Task--Parrallel--async/await 全部都是線(xiàn)程池的線(xiàn)程//直接new Thread不受這個(gè)數(shù)量限制的(但是會(huì)占用線(xiàn)程池的線(xiàn)程數(shù)量)ThreadPool.SetMaxThreads(8, 8); //設(shè)置的最大值,必須大于CPU核數(shù),否則設(shè)置無(wú)效ThreadPool.SetMinThreads(2, 2);
              Console.WriteLine("====================設(shè)置線(xiàn)程池?cái)?shù)量最大最小====================");
      
              ThreadPool.GetMaxThreads(out int workerThreads1, out int completionPortThreads1);
              Console.WriteLine($"當(dāng)前電腦最大workerThreads={workerThreads1} 最大completionPortThreads={completionPortThreads1}");
      
              ThreadPool.GetMinThreads(out int workerThreadsMin1, out int completionPortThreadsMin1);
              Console.WriteLine($"當(dāng)前電腦最大workerThreads={workerThreadsMin1} 最大completionPortThreads={completionPortThreadsMin1}");
          }//線(xiàn)程等待    {
              ManualResetEvent mre = new ManualResetEvent(false);//false---關(guān)閉---Set打開(kāi)---true---WaitOne就能通過(guò)//true---打開(kāi)--ReSet關(guān)閉---false--WaitOne就只能等待ThreadPool.QueueUserWorkItem(o =>{this.DoSomethingLong("btnThreadPool_Click1");
                  mre.Set();
              });
              Console.WriteLine("Do Something 1");
              Console.WriteLine("Do Something 2");
              Console.WriteLine("Do Something 3");
      
              mre.WaitOne();
              Console.WriteLine("任務(wù)已經(jīng)完成了。。。");
          }//寫(xiě)多線(xiàn)程的時(shí)候有這么一種說(shuō)法:不要阻塞線(xiàn)程池里面的線(xiàn)程。//下面是一個(gè)死鎖的例子    {
              ThreadPool.SetMaxThreads(8, 8);
              ManualResetEvent mre = new ManualResetEvent(false);for (int i = 0; i < 10; i++)
              {int k = i; //此處必須聲明一個(gè)變量存放i的值,不能直接使用i變量,否則會(huì)有問(wèn)題ThreadPool.QueueUserWorkItem(t =>{
                      Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId.ToString("00")} show {k}");if (k == 9) //設(shè)置了最多只允許8個(gè)線(xiàn)程,但此處是9,導(dǎo)致死鎖了                {
                          mre.Set(); //開(kāi)關(guān)打開(kāi)                }else{
                          mre.WaitOne(); //線(xiàn)程等待,阻塞                }
                  });
              }if (mre.WaitOne()) //開(kāi)關(guān)沒(méi)打開(kāi),一直等待,死鎖了        {
                  Console.WriteLine("任務(wù)全部執(zhí)行成功!");
              }
          }
      
          Console.WriteLine($"****************btnThreadPool_Click End   {Thread.CurrentThread.ManagedThreadId.ToString("00")} " +$"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
      }

      Demo源碼:

      鏈接:https://pan.baidu.com/s/1wVscaka37emNGz9x-rm0qA

      此文由博主精心撰寫(xiě)轉(zhuǎn)載請(qǐng)保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/13550714.html

      版權(quán)聲明:如有雷同純屬巧合,如有侵權(quán)請(qǐng)及時(shí)聯(lián)系本人修改,謝謝?。。?/strong>

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多