我们在项目开发的过程中可能会遇到类似后台定时任务的需求,比如消息队列的消费者。 按照 .NetF 时的开发习惯首先想到的肯定是 Windows Service ,拜托,都什么年代了还用 Windows服务
我们在项目开发的过程中可能会遇到类似后台定时任务的需求,比如消息队列的消费者。
按照.NetF
时的开发习惯首先想到的肯定是Windows Service
,拜托,都什么年代了还用Windows服务
(小声bb)
不用 Windows服务
这不是还有Quartz
之流的包嘛,也不是不行,但是随便一点小需求就上这么重的包,是不是有点大材小用了。
除了上面的方案,Task.Run
也不失为一个好方法,方便简单,直接在管道:
Task.Run(() =>
{
while (true)
{
Console.WriteLine("running");
Thread.Sleep(1000);
}
});
Ok,搞定
嗯......也不是不行,总觉得缺了点什么?难道是优雅?
IHostedServiceIHostedService
微软给的定义如下,大致的意思就是:定义主机托管对象的方法。
Defines methods for objects that are managed by the host.
下面我们就来实现一下:
public class WorkService : IHostedService, IDisposable
{
private Timer timer;
public void Dispose()
{
timer.Dispose();
}
public Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("start");
timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("end");
timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
private void DoWork(object state)
{
Console.WriteLine("running");
}
}
然后在 ConfigureServices
注册:
services.AddHostedService<WorkService>();
是不是既优雅又 so easy
。
猴:放屁,本来几行代码就能解决的,你这用了这么多行才实现,优雅个屁。
别着急,这不是赠送了两个功能嘛:start
,end
,很划算的啦。
猴:我不要这两个功能,我只要执行任务,你这个就是不行。
得,不要就不要,微软大大都给你准备好了。
BackgroundServiceBackgroundService
是微软封装的一个IHostedService
派生类,顾名思义:后台服务嘛,往下看:
public class WorkService : BackgroundService
{
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
while(!stoppingToken.IsCancellationRequested)
{
Console.WriteLine("running");
await Task.Delay(1000, stoppingToken);
}
}
}
还是一样的注册:services.AddHostedService<WorkService>();
,运行结果就...还是放一下吧。
这下够优雅了吧。
猴:那还有更优雅的吗?
年轻人,要知足(其实我也不知道了)
因为 BackgroundService
是IHostedService
的派生类,如果你想要使用 start
和end
也是可以的哦。
public override Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("start");
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("end");
return base.StopAsync(cancellationToken);
}
好了,这期的宝藏API
就到这了,下期再见哦,如果有下期的话。