在 .NET Core 3.0 辅助角色服务中管理令牌取消
Manage cancellation on the Token in a .NET Core 3.0 Worker Service
我正在开发我的第一个 .NET Core 3.0 Worker Service 运行 作为 Windows 服务。
这里是我测试用的代码
调试我看到停止 windows 服务,将执行 StopAsync(),但 ExecuteAsync() 由于异常 OperationCanceledException(从行 Task.Delay(1000,停止令牌))。
我当然可以抓住它,但我想做的是完成方法流程以便优雅地退出。
有什么方法可以避免异常,直接根据while条件退出吗?
namespace Enerj.MyAppCore.WorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
bool exit = false;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
_logger.LogInformation("ctor");
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Start");
await base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
System.Diagnostics.Debugger.Break();
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Stopping");
await Task.CompletedTask;
}
}
}
我的解决方案
从代码中可以明显看出,应用程序几乎所有时间都在 Task.Delay 中度过,因此从该代码中抛出异常是正确的。
我改了代码如下
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation($"Worker running at: {DateTime.Now}");
try
{
await Task.Delay(1000, stoppingToken);
}
catch (Exception exc)
{
_logger.LogError($"Error running at: {DateTime.Now}");
}
System.Diagnostics.Debugger.Break();
// Other code
}
我正在开发我的第一个 .NET Core 3.0 Worker Service 运行 作为 Windows 服务。
这里是我测试用的代码
调试我看到停止 windows 服务,将执行 StopAsync(),但 ExecuteAsync() 由于异常 OperationCanceledException(从行 Task.Delay(1000,停止令牌))。 我当然可以抓住它,但我想做的是完成方法流程以便优雅地退出。
有什么方法可以避免异常,直接根据while条件退出吗?
namespace Enerj.MyAppCore.WorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
bool exit = false;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
_logger.LogInformation("ctor");
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Start");
await base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
System.Diagnostics.Debugger.Break();
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Stopping");
await Task.CompletedTask;
}
}
}
我的解决方案
从代码中可以明显看出,应用程序几乎所有时间都在 Task.Delay 中度过,因此从该代码中抛出异常是正确的。
我改了代码如下
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation($"Worker running at: {DateTime.Now}");
try
{
await Task.Delay(1000, stoppingToken);
}
catch (Exception exc)
{
_logger.LogError($"Error running at: {DateTime.Now}");
}
System.Diagnostics.Debugger.Break();
// Other code
}