簡體   English   中英

.Net 5.0 和 6.0,后台服務不會像 MS 的樣本那樣停止

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

簡而言之,我正在為一個簡單的數據庫進程構建一個 TCP 服務器。 我查看了后台服務的 MS 示例,特別是 App.WorkerService。

到目前為止一切順利,可以運行該服務,並且每個應用程序實例只啟動一次 TCP 服務器。

現在我想讓服務停止,當用戶在它正在運行的命令 window 中點擊鍵盤上的 [ESC]ape 鍵。

這是 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>();
            });
  }
}

這是工人 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();
    }
  }
}

那么如何將stoppingToken.IsCancellationRequested 設置為true?

停止控制台應用程序的快捷方式是 Ctrl+C 而不是 Esc。 如果您仍然希望 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;

我還建議在您的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