BackgroundService 大佬教的好

本文介绍了.NET中的BackgroundService,它是IHostedService接口的一个抽象实现,用于后台执行任务。文章详细解析了BackgroundService的StartAsync、StopAsync方法,并展示了如何通过重写ExecuteAsync方法来实现周期性任务。作者还提供了一个扩展示例,展示如何创建一个轮询服务,并在需要时停止。最后,作者鼓励读者通过这种方式提高代码的优雅性和可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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个女朋友!!!!");
              }
       }

最后总结愿望成真

### 如何设计或优化卷积神经网络(CNN) #### 设计原则 在设计卷积神经网络时,需考虑以下几个方面: - **层数的选择**:增加网络的深度通常可以提升性能,但也会带来过拟合的风险以及计算成本的上升。因此,在实际应用中需要权衡复杂度与资源消耗之间的关系[^1]。 - **滤波器尺寸**:常用的滤波器大小为 \(3 \times 3\) 或 \(5 \times 5\)。较小的滤波器能够捕捉局部特征并减少参数数量;而较大的滤波器则有助于获取更广泛的上下文信息。 - **步幅和填充**:调整这些超参数会影响输出的空间维度及其感受野范围。适当设置可以使模型更好地适应特定任务需求[^3]。 #### 优化方法 为了进一步改善CNN的表现力,可以从如下几个角度入手进行优化: - **正则化技术的应用**:Dropout是一种有效的防止过拟合的方法之一,它随机丢弃一部分神经元从而强制让其他未被选中的单元承担更多责任来学习数据分布规律[^2]。 - **批量归一化(Batch Normalization)**:通过对每一层输入做标准化处理使得整个训练过程更加稳定快速收敛[^4]。 - **激活函数选取**:ReLU(Rectified Linear Unit)因其简单高效成为主流选择,不过也有研究表明Leaky ReLU或者ELU等变体可能更适合某些场景下的表现[^5]。 ```python import tensorflow as tf from tensorflow.keras import layers, models model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dropout(0.5)) model.add(layers.Dense(10, activation='softmax')) model.compile(optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) ``` 上述代码展示了一个基础版本的CNN结构定义流程,并包含了简单的正则化措施——即dropout操作以增强泛化能力。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值