简体   繁体   English

.Net 5.0 和 6.0,后台服务不会像 MS 的样本那样停止

[英].Net 5.0 and 6.0, background service not stopping like samples from MS

In short I'm building a TCP server for a simple DB process.简而言之,我正在为一个简单的数据库进程构建一个 TCP 服务器。 I looked at the MS samples for background service specifically the App.WorkerService.我查看了后台服务的 MS 示例,特别是 App.WorkerService。

So far so good, can run the service and it only starts the TCP server once per app instance.到目前为止一切顺利,可以运行该服务,并且每个应用程序实例只启动一次 TCP 服务器。

Now I want to have the service stopped when a user, in the command window it is running, hits the [ESC]ape key on the keyboard.现在我想让服务停止,当用户在它正在运行的命令 window 中点击键盘上的 [ESC]ape 键。

Here is the Program.cs:这是 Program.cs:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace PostDataService
{
  public class Program
  {
    public static void Main(string[] args)
    {
      CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
              services.AddHostedService<Worker>();
            });
  }
}

Here is the Worker class:这是工人 class:

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
using WatsonTcp;

namespace PostDataService
{
  public class Worker : BackgroundService
  {
    private readonly ILogger<Worker> _logger;
    private int _serverPort = 1701;
    private static WatsonTcpServer _Server;

    public Worker(ILogger<Worker> logger)
    {
      _logger = logger;
      _Server = new(null, _serverPort);
      _Server.Events.ClientConnected += ClientConnected;
      _Server.Events.ClientDisconnected += ClientDisconnected;
      _Server.Events.MessageReceived += MsgReceived;
      _Server.Start();
    }

    private void MsgReceived(object sender, MessageReceivedEventArgs args)
    {
      Console.WriteLine("Got Msg");
    }

    private void ClientDisconnected(object sender, DisconnectionEventArgs args)
    {
      throw new NotImplementedException();
    }

    private void ClientConnected(object sender, ConnectionEventArgs args)
    {
      throw new NotImplementedException();
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
      while (!stoppingToken.IsCancellationRequested)
      {
        _logger.LogInformation("Worker running at: {time} {threadid}", DateTimeOffset.Now, Thread.CurrentThread.ManagedThreadId );

        await Task.Delay(500, stoppingToken);
      }
      _Server.Stop();
    }
  }
}

So how would I get the stoppingToken.IsCancellationRequested set to true?那么如何将stoppingToken.IsCancellationRequested 设置为true?

The shortcut to stop console application is Ctrl+C not Esc.停止控制台应用程序的快捷方式是 Ctrl+C 而不是 Esc。 If you still want Esc to be working you can do something like this:如果您仍然希望 Esc 正常工作,您可以执行以下操作:

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker>();
    })
    .Build();

var hostTask = host.RunAsync();

// listen for Esc 
_ = Task.Run(async () =>
{
    ConsoleKeyInfo key;
    do
    {
        key = Console.ReadKey();
    }
    while (key.Key != ConsoleKey.Escape);
    await host.StopAsync();
});

await hostTask;

Also I recommend adding something like this in your Worker :我还建议在您的Worker中添加类似的内容:

public override Task StopAsync(CancellationToken cancellationToken)
{ 
    _logger.LogInformation("stopping server");
    _Server.Stop();
    return Task.CompletedTask;  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM