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

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

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

      .NET Core 實現(xiàn)后臺任務(wù)(定時任務(wù))BackgroundService(二)

      原文連接:http://www.rzrgm.cn/ysmc/p/16468560.html

        在上一篇文檔中說到使用 IHostedService 接口實現(xiàn)定時任務(wù)  傳送門,其中,有小伙伴就問到,為什么不使用 BackgroundService,我個人覺得使用什么技術(shù),應(yīng)該取決于需求,代碼只是一種工具,用得順手對于編碼人員來說,我個人感覺還是非常重要的;正好也說到了 BackgroundService,那這一篇文檔就簡單說一下它吧。

        首先我們看一下官方的說明,學(xué)習(xí)代碼一定要看官方的文檔,盡管有時候會有點晦澀難懂,但肯定是最正確的:


      BackgroundService 基類

      BackgroundService 是用于實現(xiàn)長時間運行的 IHostedService 的基類。

      調(diào)用 ExecuteAsync(CancellationToken) 來運行后臺服務(wù)。 實現(xiàn)返回一個 Task,其表示后臺服務(wù)的整個生存期。

      在 ExecuteAsync 變?yōu)楫惒剑ɡ缤ㄟ^調(diào)用 await)之前,不會啟動任何其他服務(wù)。 避免在 ExecuteAsync 中執(zhí)行長時間的阻塞初始化工作。 

      StopAsync(CancellationToken) 中的主機塊等待完成 ExecuteAsync

      調(diào)用 IHostedService.StopAsync 時,將觸發(fā)取消令牌。 當(dāng)激發(fā)取消令牌以便正常關(guān)閉服務(wù)時,ExecuteAsync 的實現(xiàn)應(yīng)立即完成。 否則,服務(wù)將在關(guān)閉超時后不正常關(guān)閉。

      StartAsync 應(yīng)僅限于短期任務(wù),因為托管服務(wù)是按順序運行的,在 StartAsync 運行完成之前不會啟動其他服務(wù)。 長期任務(wù)應(yīng)放置在 ExecuteAsync 中。


        針對第一點“BackgroundService 是用于實現(xiàn)長時間運行的 IHostedService 的基類”,我們先看看 BackgroundService 的源碼:

       1 public abstract class BackgroundService : IHostedService, IDisposable
       2 {
       3     private Task _executingTask;
       4     private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
       5 
       6     /// <summary>
       7     /// This method is called when the <see cref="IHostedService"/> starts. The implementation should return a task that represents
       8     /// the lifetime of the long running operation(s) being performed.
       9     /// /// </summary>
      10     /// <param name="stoppingToken">Triggered when <see cref="IHostedService.StopAsync(CancellationToken)"/> is called.</param>
      11     /// <returns>A <see cref="Task"/> that represents the long running operations.</returns>
      12     protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
      13 
      14     /// <summary>
      15     /// Triggered when the application host is ready to start the service.
      16     /// </summary>
      17     /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
      18     public virtual Task StartAsync(CancellationToken cancellationToken)
      19     {
      20         // Store the task we're executing
      21         _executingTask = ExecuteAsync(_stoppingCts.Token);
      22 
      23         // If the task is completed then return it, this will bubble cancellation and failure to the caller
      24         if (_executingTask.IsCompleted)
      25         {
      26             return _executingTask;
      27         }
      28 
      29         // Otherwise it's running
      30         return Task.CompletedTask;
      31     }
      32 
      33     /// <summary>
      34     /// Triggered when the application host is performing a graceful shutdown.
      35     /// </summary>
      36     /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
      37     public virtual async Task StopAsync(CancellationToken cancellationToken)
      38     {
      39         // Stop called without start
      40         if (_executingTask == null)
      41         {
      42             return;
      43         }
      44 
      45         try
      46         {
      47             // Signal cancellation to the executing method
      48             _stoppingCts.Cancel();
      49         }
      50         finally
      51         {
      52             // Wait until the task completes or the stop token triggers
      53             await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
      54         }
      55 
      56     }
      57 
      58     public virtual void Dispose()
      59     {
      60         _stoppingCts.Cancel();
      61     }
      62 }

        以上代碼很好的解答了小伙伴提出“為什么不使用 BackgroundService”的問題,在上一篇文章中,評論區(qū)的一位大佬也很好的回答了這位小伙伴的問題,我這里引用下這位大佬的原話:“BackgroundService 是 IHostedService的一個簡單實現(xiàn),內(nèi)部IHostedService 的StartAsync調(diào)用了ExecuteAsync”,本質(zhì)上就是使用了 IHostedService;

        讓我們回到正題,怎么用 BackgroundService 實現(xiàn)定時任務(wù)呢,老規(guī)矩,上代碼:

      首先,創(chuàng)建一個服務(wù)接口,定義需要實現(xiàn)的任務(wù),以及對應(yīng)的實現(xiàn),如果需要執(zhí)行異步方法,記得加上 await,不然任務(wù)將不會等待執(zhí)行結(jié)果,直接進行下一個任務(wù)。

       1 public class TaskWorkService : ITaskWorkService
       2 {
       3     public async Task TaskWorkAsync(CancellationToken stoppingToken)
       4     {
       5         while (!stoppingToken.IsCancellationRequested)
       6         {
       7             //執(zhí)行任務(wù)
       8             Console.WriteLine($"{DateTime.Now}");
       9 
      10             //周期性任務(wù),于上次任務(wù)執(zhí)行完成后,等待5秒,執(zhí)行下一次任務(wù)
      11             await Task.Delay(500);
      12         }
      13     }
      14 }

        注冊服務(wù)

      builder.Services.AddScoped<ITaskWorkService, TaskWorkService>();

        創(chuàng)建后臺服務(wù)類,繼承基類 BackgroundService,這里需要注意的是,要在 BackgroundService 中使用有作用域的服務(wù),請創(chuàng)建作用域, 默認情況下,不會為托管服務(wù)創(chuàng)建作用域,得自己管理服務(wù)的生命周期,切記!于構(gòu)造函數(shù)中注入 IServiceProvider即可。

       1 public class BackgroundServiceDemo : BackgroundService
       2 {
       3     private readonly IServiceProvider _services;
       4 
       5     public BackgroundServiceDemo(IServiceProvider services)
       6     {
       7         _services = services;
       8     }
       9 
      10     protected override async Task ExecuteAsync(CancellationToken stoppingToken)
      11     {
      12         using var scope = _services.CreateScope();
      13 
      14         var taskWorkService = scope.ServiceProvider.GetRequiredService<ITaskWorkService>();
      15 
      16         await taskWorkService.TaskWorkAsync(stoppingToken);
      17     }
      18 }

        最后別忘了這個類也是需要注冊的,注冊方式與 IHostedService 接口的方式一樣

      builder.Services.AddHostedService<BackgroundServiceDemo>();

        大功告成,F(xiàn)5看看效果吧

      寫在最后

      Bootstrap Blazor 官網(wǎng)地址:https://www.blazor.zone

        希望大佬們看到這篇文章,能給項目點個star支持下,感謝各位!

      star流程:

      1、訪問點擊項目鏈接:BootstrapBlazor   star

      2、點擊star,如下圖,即可完成star,關(guān)注項目不迷路:

       

      另外還有兩個GVP項目,大佬們方便的話也點下star唄,非常感謝:

        BootstrapAdmin 項目地址:star
        https://gitee.com/LongbowEnterprise/BootstrapAdmin

        SliderCaptcha 項目地址:star
        https://gitee.com/LongbowEnterprise/SliderCaptcha

       

      交流群(QQ)歡迎加群討論

             BA & Blazor ①(795206915)          BA & Blazor ②(675147445)

      posted @ 2022-07-13 00:26  一事冇誠  閱讀(10106)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 国产免费视频一区二区| 中文精品无码中文字幕无码专区| 99九九视频高清在线| 天堂va欧美ⅴa亚洲va在线| 蜜桃av一区二区高潮久久精品| 国产成人8X人网站视频| 日韩欧美卡一卡二卡新区| 天天综合色一区二区三区| 国产综合久久99久久| 亚洲日本精品一区二区| 18av千部影片| 精品亚洲欧美无人区乱码| 老熟妇欲乱一区二区三区| 久久久久人妻精品一区三寸 | 国产主播精品福利午夜二区| 美女裸体黄网站18禁止免费下载| 91福利视频一区二区| 国产欧美另类久久久精品不卡| 国产区二区三区在线观看| 久久人妻无码一区二区三区av| 成人性生交大片免费看r老牛网站 中文字幕一区二区三区四区五区 久久久久久毛片免费播放 | 日韩av一区二区三区不卡| 中文字幕av一区二区三区| 国产精品久久久国产盗摄| 国产精品成人av在线观看春天| 成熟熟女国产精品一区二区| av深夜免费在线观看| 东京热大乱系列无码| 久久天天躁夜夜躁狠狠躁2022| 亚洲 小说区 图片区 都市| 国内自拍小视频在线看| 天堂在线最新版av观看| 国产亚洲精品VA片在线播放| 巨熟乳波霸若妻在线播放| 亚洲老熟女一区二区三区| 日韩一区二区三区一级片| 中文精品无码中文字幕无码专区 | 色综合国产一区二区三区| 精品一精品国产一级毛片| 成人国产精品中文字幕| 久久精品噜噜噜成人av|