我想知道如何才能关闭 IHost
的执行,例如30秒后。
IHost host = new HostBuilder()
.UseConsoleLifetime()
.Build();
using (host)
{
await host.RunAsync();
}
我试图用
services.AddOptions<HostOptions>().Configure(
opts => opts.ShutdownTimeout = TimeSpan.FromSeconds(10));
徒劳无功
请看一下我的.NET Core 3.1控制台应用程序的代码和附带的控制台输出的截图。这个应用程序演示了所要求的功能。当主机启动时,托管服务会向控制台打印数字,每2秒一个数字。一旦主机收到关闭命令,"应用程序正在关闭...... "的消息将被写入控制台,而托管服务将继续其工作。当指定的超时时间过后,应用程序就会关闭。如果你想在托管服务中允许处理取消已执行的任务,我在方法ExecuteAsync中的注释代码演示了这一点,那么主机在取消已执行的任务后就完成了它的工作,而无需等待指定的超时。
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace ConsoleApp38
{
public class Program
{
public static async Task Main(string[] args)
{
try
{
using (var host = new MyHost())
{
await host.StartAsync();
Console.WriteLine(@"Host has started. Please Press Enter or ""Ctrl + C"" to stop the host");
Console.ReadLine();
await host.StopAsync();
Console.ReadLine();
}
}
catch (Exception e)
{
//log any exceptions here;
}
}
}
public class MyHost : IHost
{
private static IHost _host;
public MyHost()
{
IHostBuilder builder = Host.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.Configure<HostOptions>(option =>
{
option.ShutdownTimeout = System.TimeSpan.FromSeconds(30);
});
services.AddHostedService<MyHostedService>();
});
_host = builder.Build();
}
public IServiceProvider Services
{
get { return _host.Services; }
}
public void Dispose()
{
_host.Dispose();
}
public async Task StartAsync(CancellationToken cancellationToken = default(CancellationToken))
{
await _host.StartAsync(cancellationToken);
}
public async Task StopAsync(CancellationToken cancellationToken = default(CancellationToken))
{
await _host.StopAsync(cancellationToken);
}
}
public class MyHostedService : BackgroundService
{
public async Task StartAsync(CancellationToken cancellationToken)
{
}
public async Task StopAsync(CancellationToken cancellationToken)
{
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
for (int i = 0; i <= 100; i++)
{
//if you allow canceling this task here then the host will be shut down
//right after completion of this method without the specified timeout
//if (stoppingToken.IsCancellationRequested) break;
await Task.Delay(2000);
Console.WriteLine(i);
}
}
}
}
更新:虽然程序在Windows 7 64位上超时关闭,但在Ubuntu 18.04 64位上却没有超时关闭。我没有在其他操作系统上尝试这段代码。