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

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

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

      Loading

      LongRunningTask-正確用法

      在上一篇文章《如何正確實現一個 BackgroundService》中有提到 LongRunning 來優化后臺任務始終保持在同一個線程上。

              protected override Task ExecuteAsync(CancellationToken stoppingToken)
              {
                  return Task.Factory.StartNew(async () =>
                  {
                      while (!stoppingToken.IsCancellationRequested)
                      {
                          // Simulate some work
                          Console.WriteLine("HostServiceTest_A is doing work.");
      
                          LongTermTask();
      
                          await Task.Delay(1000, stoppingToken); // Delay for 1 second
                      }
      
                      Console.WriteLine("HostServiceTest_A task done.");
      
                  }, TaskCreationOptions.LongRunning);
              }
      
              private void LongTermTask()
              {
                  // Simulate some work
                  Console.WriteLine("LongTermTaskA is doing work.");
                  Thread.Sleep(30000);
              }
      

      但是被黑洞視界 大佬指出這個用法是錯誤的:以上用法并不能保證任務始終在同一個 Task(線程) 上執行。原因是當碰到第一個 await 之后運行時會從 ThreadPool 中調度一個新的線程來執行后面的代碼,而當前線程被釋放。這個時候就不符合我們使用 LongRunning 的期望了。

      在 .NET 中,Task.Factory.StartNew 提供了 TaskCreationOptions.LongRunning 選項,很多開發者會用它來啟動長時間運行的任務,并且想當然的認為它會永遠執行在同一個線程上。但是事實上當遇到 async await 的時候并想象的那么簡單。

      下面我們還是通過一個錯誤的示例開始講解如何正確的使用它。

      錯誤用法

      很多人會直接在 Task.Factory.StartNew 里傳入一個 async 方法:

      // See https://aka.ms/new-console-template for more information
      Console.WriteLine("Hello, World!");
      
      var task = Task.Factory.StartNew(async () =>
      {
          Console.WriteLine($"long running task starting. Thread id: {Thread.CurrentThread.ManagedThreadId}");
          var loopCount = 1;
          while (true)
          {
              Console.WriteLine($"\r\nStart: loop count: {loopCount}, Thread id: {Thread.CurrentThread.ManagedThreadId}");
              await LongRunningJob();
              Console.WriteLine($"End: loop count: {loopCount}, Thread id: {Thread.CurrentThread.ManagedThreadId} \r\n ");
              loopCount++;
          }
      
      }, TaskCreationOptions.LongRunning);
      
      
      static async Task LongRunningJob()
      {
          Console.WriteLine($"task doing. Thread id: {Thread.CurrentThread.ManagedThreadId}");
          await Task.Delay(1000);
      }
      
      Console.ReadLine();
      

      輸出:

      Hello, World!
      long running task starting. Thread id: 12
      
      Start: loop count: 1, Thread id: 12
      task doing. Thread id: 12
      End: loop count: 1, Thread id: 11
      
      
      Start: loop count: 2, Thread id: 11
      task doing. Thread id: 11
      End: loop count: 2, Thread id: 11
      

      可以看到,第一次循環后,線程 id 發生了變化。很明顯 LongRunning 失效了。原因開篇已經講了,不在贅述。

      正確用法 1:同步方法

      LongRunningJob 改為同步方法,避免異步切換線程:

      var task = Task.Factory.StartNew(() =>
      {
          Console.WriteLine($"long running task starting. Thread id: {Thread.CurrentThread.ManagedThreadId}");
          var loopCount = 1;
          while (true)
          {
              Console.WriteLine($"\r\nStart: loop count: {loopCount}, Thread id: {Thread.CurrentThread.ManagedThreadId}");
              LongRunningJob();
              Console.WriteLine($"End: loop count: {loopCount}, Thread id: {Thread.CurrentThread.ManagedThreadId} \r\n ");
              loopCount++;
          }
      
      }, TaskCreationOptions.LongRunning);
      
      
      static void LongRunningJob()
      {
          Console.WriteLine($"task doing. Thread id: {Thread.CurrentThread.ManagedThreadId}");
          Thread.Sleep(1000);
      }
      

      輸出:

      Hello, World!
      long running task starting. Thread id: 12
      
      Start: loop count: 1, Thread id: 12
      task doing. Thread id: 12
      End: loop count: 1, Thread id: 12
      

      線程 id 始終不變,說明始終運行在專用線程上。

      正確用法 2:異步方法同步等待

      如果必須用異步方法,可以用 .Wait() 讓調用變為同步:

      var task = Task.Factory.StartNew(() =>
      {
          Console.WriteLine($"long running task starting. Thread id: {Thread.CurrentThread.ManagedThreadId}");
          var loopCount = 1;
          while (true)
          {
              Console.WriteLine($"\r\nStart: loop count: {loopCount}, Thread id: {Thread.CurrentThread.ManagedThreadId}");
              LongRunningJob().Wait();
              Console.WriteLine($"End: loop count: {loopCount}, Thread id: {Thread.CurrentThread.ManagedThreadId} \r\n ");
              loopCount++;
          }
      
      }, TaskCreationOptions.LongRunning);
      
      
      static async Task LongRunningJob()
      {
          Console.WriteLine($"task doing. Thread id: {Thread.CurrentThread.ManagedThreadId}");
          await Task.Delay(1000);
      }
      

      輸出:

      Hello, World!
      long running task starting. Thread id: 12
      
      Start: loop count: 1, Thread id: 12
      task doing. Thread id: 12
      End: loop count: 1, Thread id: 12
      

      總結

      • TaskCreationOptions.LongRunning 適用于同步、阻塞型任務。
      • 不要在 StartNew 里直接用 async 方法。
      • 如果必須用異步方法,需同步等待(如 .Wait())。

      希望本文能幫你正確理解和使用 LongRunning 任務!

      最后,再次感謝黑洞視界指出問題。如果對于這個問題大家希望了解更多,可以拜讀大佬的這篇文章:
      http://www.rzrgm.cn/eventhorizon/p/17497359.html

      posted @ 2025-08-04 22:05  Agile.Zhou  閱讀(452)  評論(4)    收藏  舉報
      主站蜘蛛池模板: 亚洲加勒比久久88色综合| 丰满少妇69激情啪啪无| 熟女人妻aⅴ一区二区三区电影| 国产三级精品三级在线看| 福利一区二区1000| 国产jlzzjlzz视频免费看| 国产精品香港三级国产av| 黑人大战中国av女叫惨了| 欧洲熟妇熟女久久精品综合| 久久精品一本到99热免费| 精品日韩人妻中文字幕| 亚洲精品www久久久久久| 精品国产AV无码一区二区三区| 人妻系列无码专区免费 | 九九热视频免费在线播放| 亚洲精品在线二区三区| 亚洲A综合一区二区三区| 国产片一区二区三区视频| aa级毛片毛片免费观看久| 18禁亚洲一区二区三区| 久久亚洲精品中文字幕| 亚洲精品韩国一区二区| 99久久精品久久久久久婷婷| 无码 人妻 在线 视频| 亚洲人成人一区二区三区| 国产精品久久无码一区| 亚洲国产成人久久精品不卡| 色爱综合另类图片av| 亚州中文字幕一区二区| 国产精品小仙女自拍视频| 精品熟女日韩中文十区| 四虎影视4hu4虎成人| 增城市| 18禁视频一区二区三区| 国产精品一区在线蜜臀 | 亚洲国产高清第一第二区| 色色97| 欧美激情一区二区久久久| 体育| 国产精品大全中文字幕| 久久久久四虎精品免费入口|