zoukankan      html  css  js  c++  java
  • BackgroundService 大佬教的好

    BackgroundService 源码分析

    因为换了工作也有两个多月没有写博客啦,因为跟着红超哥(大佬)一直在学习和做项目(反正就是在潜心修炼,大佬每天也是在我十万个为什么中度过的。)

    • 最近在做一个接收服务端信息的项目,使用TCP建立连接,双方进行信息通信。后面我会陆陆续续的把自己学习的东西进行一个是输出。
    • 当时有一个需求需要在程序初始化完毕之后,执行一些不干扰主要流程的代码 (说时猛,那时快,聪明的我马上想到了新起一个线程去执行)。
        // 类似于这样写
        Task.Run(() =>
        {
            Console.WriteLine("年轻人");
          }).Start();
    

    很快啊 很快,红超哥就眼神就不对了,完了,完了。当时我就知道红超哥又要教我了。果不其然红超哥和我说可以使用BackgroundService也就是今天的主角。

    当时我满脑子都在想一个剧情
    红超哥:年轻人你这样写代码不优雅,可读性不好,你在这里练死劲没用。
    我:有用! 特别有用
    ...... (后面我没用)ps:上剧情纯属玩笑

    BackgroundService是什么

    • 但是我看到这名字就知道不简单了,Background背后+Service服务==背后的干活
    • 其实也就是我们理解的字面意思,BackgroundService是一个抽象类,继承IHostedService然后就拥有了StartAsync()、StopAsync()方法。
    • 当我们继承BackgroundService之后需要重写ExecuteAsync抽象方法,然后我们只需要在ExecuteAsync方法中写入自己需要执行的方法就可以了。
    • 然后在配置服务中心注入该方法就可以了services.AddHostedService();,
    • 你就已经完成来了自己的任务了,是不是感觉很简单呢?(逐渐了忘记了标题)

    BackgroundService实现方式

    • 我们通过F12可以进入源码中查看,整体的代码结构。继承IHostedService之后实现了StartAsync()、StopAsync()方法,但是多了一个ExecuteAsync方法和_executingTask字段、CancellationTokenSource标记
    • _executingTask是一个线程变量,主要用于存储异步ExecuteAsync方法
    • CancellationTokenSource标记源,这个我在Task博文中介绍过,用于取消线程进行。
    • 重点说一下StartAsync会在程序所有配置加载完之后才会执行。

    BackgroundService拓展

    现在我们要实现一个轮询需求,我们需要怎么做呢?(此时此刻我想望向红超哥,但是我一个人出差了,所以只能自己实现了)

           public abstract class InitBackgroundWork : BackgroundService
           {
                  //创建一个取消标记源
                  private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    
                  //入参委托
                  private Action<object> action;
    
                  //方法初始话
                  protected void Init()
                  {
                         action = async e =>
                         {
                               while (true)
                               {
                                      DoWork(e);
                                      await Task.Delay(TimeSpan.FromSeconds(10));
                               }
                         };
                  }
    
                  /// <summary>
                  /// 执行方法
                  /// </summary>
                  /// <param name="stoppingToken"></param>
                  /// <returns></returns>
                  protected override Task ExecuteAsync(CancellationToken stoppingToken)
                  {
                         Init();
                         _ = Task.Factory.StartNew(action, cancellationTokenSource.Token);
                         return Task.CompletedTask;
                  }
    
                  /// <summary>
                  /// 我们重写一下关闭方法
                  /// </summary>
                  /// <param name="cancellationToken"></param>
                  /// <returns></returns>
                  public override Task StopAsync(CancellationToken cancellationToken)
                  {
                         cancellationTokenSource.Cancel();
                         return base.StopAsync(cancellationToken);
                  }
    
                  //抛出方法入口
                  protected abstract void DoWork(object state);
           }
    

    这样我们只需要管入口方法就好了,创建一个类继承它,然后在配置服务中AddHostedService添加就好了,我们也可以直接通过开始方法、结束方法控制就好了

           public class  GetGirlfriend: InitBackgroundWork
           {
                  protected override void DoWork(object state)
                  {
                         Console.WriteLine("给我1个女朋友!!!!");
                  }
           }
    

    最后总结愿望成真

  • 相关阅读:
    [置顶] Android中定时器的3种实现方法
    [置顶] Android代码应用程序通过WakeLock保持后台唤醒状态
    [置顶] 当爱情遇上互联网
    [置顶] Android咨询阿米巴基金合伙人李治国:我为什么投资快的打车?
    [置顶] Android问题Getting Android Sensor Events While The Screen is Off
    静态SQL和动态SQL
    IBM Data Studio使用对象创建的双引号/大小写问题以及表/列重命名
    DB2数据库查询过程(Query Processing)统计信息与过滤因子(Statistics and Filter Factors)
    DB2数据库查询过程(Query Processing)概述
    DB2数据库查询过程(Query Processing)表扫描与I/O(Table Scan and I/O)
  • 原文地址:https://www.cnblogs.com/chenxi001/p/14057460.html
Copyright © 2011-2022 走看看