我有一个简单的.net核心控制台应用程序,有几个长期运行的后台服务。服务在应用程序启动时启动。我想在用户请求时正确地停止它们。微软提供了实现长时间运行的基类- BackgroundService。
public abstract class BackgroundService : IHostedService, IDisposable
{
private readonly CancellationTokenSource _stoppingCts = new CancellationTokenSource();
private Task _executingTask;
/// <summary>
/// This method is called when the <see cref="T:Microsoft.Extensions.Hosting.IHostedService" /> starts. The implementation should return a task that represents
/// the lifetime of the long running operation(s) being performed.
/// </summary>
/// <param name="stoppingToken">Triggered when <see cref="M:Microsoft.Extensions.Hosting.IHostedService.StopAsync(System.Threading.CancellationToken)" /> is called.</param>
/// <returns>A <see cref="T:System.Threading.Tasks.Task" /> that represents the long running operations.</returns>
protected abstract Task ExecuteAsync(CancellationToken stoppingToken);
/// <summary>
/// Triggered when the application host is ready to start the service.
/// </summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
public virtual Task StartAsync(CancellationToken cancellationToken)
{
this._executingTask = this.ExecuteAsync(this._stoppingCts.Token);
if (this._executingTask.IsCompleted)
return this._executingTask;
return Task.CompletedTask;
}
/// <summary>
/// Triggered when the application host is performing a graceful shutdown.
/// </summary>
/// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>
public virtual async Task StopAsync(CancellationToken cancellationToken)
{
if (this._executingTask == null)
return;
try
{
this._stoppingCts.Cancel();
}
finally
{
Task task = await Task.WhenAny(this._executingTask, Task.Delay(-1, cancellationToken));
}
}
public virtual void Dispose()
{
this._stoppingCts.Cancel();
}BackgroundService允许通过调用StopAsync方法来停止服务。此外,我们还可以通过这种方式实现长时间运行的服务,使用单个方法和取消令牌:
public class LongRunningService
{
public Task RunAsync(CancellationToken token)
{
return Task.Factory.StartNew(() =>
{
// here goes something long running
while (!token.IsCancellationRequested)
{
}
},
TaskCreationOptions.LongRunning);
}
}这两种方法都解决了我的问题。但是,我不能决定哪一个在代码组织和匹配类语义方法方面更好。你会选择什么方法?为什么?
发布于 2021-12-19 17:37:10
经过几年的发展,我准备回答我自己的问题。希望这能对其他人有所帮助。
如果你需要在你的应用程序的所有生命周期中处理一些东西,你应该选择后台服务(例如。监督狗,评级更新者,背景电子邮件/短信发送者)。
如果您只需要运行任何类型的长期运行,但时间有限的操作,您应该选择Task.Factory.StartNew与长期运行的选项。
在大多数情况下,当您创建一个.NET Core应用程序时,后台服务可以满足大多数情况,因为在web应用程序或后台工作人员中,通常不需要手动从代码中运行长期运行的任务。
https://stackoverflow.com/questions/52643191
复制相似问题