首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >停止子系统:单CancellationToken与停止方法

停止子系统:单CancellationToken与停止方法
EN

Stack Overflow用户
提问于 2018-10-04 09:17:05
回答 1查看 364关注 0票数 2

我有一个简单的.net核心控制台应用程序,有几个长期运行的后台服务。服务在应用程序启动时启动。我想在用户请求时正确地停止它们。微软提供了实现长时间运行的基类- BackgroundService

代码语言:javascript
运行
复制
 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方法来停止服务。此外,我们还可以通过这种方式实现长时间运行的服务,使用单个方法和取消令牌:

代码语言:javascript
运行
复制
public class LongRunningService
{
    public Task RunAsync(CancellationToken token)
    {
        return Task.Factory.StartNew(() =>
            {
                // here goes something long running
                while (!token.IsCancellationRequested)
                {

                }
            },
            TaskCreationOptions.LongRunning);
    }
}

这两种方法都解决了我的问题。但是,我不能决定哪一个在代码组织和匹配类语义方法方面更好。你会选择什么方法?为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-19 17:37:10

经过几年的发展,我准备回答我自己的问题。希望这能对其他人有所帮助。

如果你需要在你的应用程序的所有生命周期中处理一些东西,你应该选择后台服务(例如。监督狗,评级更新者,背景电子邮件/短信发送者)。

如果您只需要运行任何类型的长期运行,但时间有限的操作,您应该选择Task.Factory.StartNew与长期运行的选项。

在大多数情况下,当您创建一个.NET Core应用程序时,后台服务可以满足大多数情况,因为在web应用程序或后台工作人员中,通常不需要手动从代码中运行长期运行的任务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52643191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档