繁体   English   中英

服务应该如何退出以防止错误?

[英]How should a service exit to prevent an error?

我正在按照https://learn.microsoft.com/en-us/do.net/core/extensions/windows-service上的说明在 C#、.NET 6.0 中开发一个 Windows 服务该服务按预期运行,但是当我停止服务,它记录一个错误

任务已取消。

异常:System.Threading.Tasks.TaskCanceledException:任务已取消。 在 AWLService.WindowsBackgroundService.ExecuteAsync(CancellationToken stoppingToken) 在 C:\Minerva\Projects\AWLService_Test\WindowsBackgroundService.cs:line 22

该程序的 ExecuteAsync 如下所示:

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                string joke = _jokeService.GetJoke();
                _logger.LogWarning("{Joke}", joke);

                await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "{Message}", ex.Message);

            // Terminates this process and returns an exit code to the operating system.
            // This is required to avoid the 'BackgroundServiceExceptionBehavior', which
            // performs one of two scenarios:
            // 1. When set to "Ignore": will do nothing at all, errors cause zombie services.
            // 2. When set to "StopHost": will cleanly stop the host, and log errors.
            //
            // In order for the Windows Service Management system to leverage configured
            // recovery options, we need to terminate the process with a non-zero exit code.
            Environment.Exit(1);
        }
    }

我试过捕获 TaskCanceledException。 当我这样做并添加 Environment.Exit(0) 时,我仍然收到错误。 如果我取出 Environment.Exit,该服务将无错误终止,但它会记录两次“服务已成功停止”。

我结束服务的正确方式是什么?

谢谢。

编辑:我为 TaskCanceledException 添加了一个处理程序,如下所示:

catch (TaskCanceledException ex)
{
    //Do nothing, we're exiting normally.
    Environment.Exit(0);
}

当我这样做时,通过 MMC 停止服务会显示错误“错误 1067:进程意外终止”,并且不会记录指示服务已停止的消息。 在命令行上使用 sc 停止它不会显示错误,但它也不会记录服务已停止的消息。

如果我删除Environment.Exit(0)行,MMC 不再显示错误,但“服务已成功停止”日志消息被写入两次。

捕获OperationCancelledException并在处理程序中向控制台记录不同的内容。 我怀疑在你原来的处理程序(未显示)中你仍然可能这样做: _logger.LogError(ex, "{Message}", ex.Message);

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    try
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            string joke = _jokeService.GetJoke();
            _logger.LogWarning("{Joke}", joke);

            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        }
    }
    catch (OperationCancelledException)
    {
        _logger.LogInformation("The service has stopped");
        Environment.Exit(0);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "{Message}", ex.Message);
    }
}

暂无
暂无

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

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