我正在构建一个简单的.NET Core控制台应用程序,它将从命令行读取基本选项,然后在没有用户交互的情况下执行并终止。我想利用DI,所以我使用了.NET Core通用主机。
我找到的所有构建控制台应用程序的示例都创建了一个实现IHostedService或扩展BackgroundService的类。然后,通过AddHostedService将该类添加到服务容器中,并通过StartAsync或ExecuteAsync开始应用程序的工作。但是,在所有这些示例中,它们都是在实现后台服务或其他运行循环或等待请求的应用程序,直到被操作系统关闭或收到某个请求终止为止。如果我只想要一个启动、执行操作,然后退出的应用程序怎么办?例如:
Program.cs:
我找到的所有构建控制台应用程序的示例都创建了一个实现IHostedService或扩展BackgroundService的类。然后,通过AddHostedService将该类添加到服务容器中,并通过StartAsync或ExecuteAsync开始应用程序的工作。但是,在所有这些示例中,它们都是在实现后台服务或其他运行循环或等待请求的应用程序,直到被操作系统关闭或收到某个请求终止为止。如果我只想要一个启动、执行操作,然后退出的应用程序怎么办?例如:
Program.cs:
namespace MyApp
{
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
public static class Program
{
public static async Task Main(string[] args)
{
await CreateHostBuilder(args).RunConsoleAsync();
}
private static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureLogging(builder => builder.SetMinimumLevel(LogLevel.Warning))
.ConfigureServices((hostContext, services) =>
{
services.Configure<MyServiceOptions>(hostContext.Configuration);
services.AddHostedService<MyService>();
services.AddSingleton(Console.Out);
});
}
}
MyServiceOptions.cs:
namespace MyApp
{
public class MyServiceOptions
{
public int OpCode { get; set; }
public int Operand { get; set; }
}
}
我的服务.cs:
namespace MyApp
{
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
public class MyService : IHostedService
{
private readonly MyServiceOptions _options;
private readonly TextWriter _outputWriter;
public MyService(TextWriter outputWriter, IOptions<MyServiceOptions> options)
{
_options = options.Value;
_outputWriter = outputWriter;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_outputWriter.WriteLine("Starting work");
DoOperation(_options.OpCode, _options.Operand);
_outputWriter.WriteLine("Work complete");
}
public async Task StopAsync(CancellationToken cancellationToken)
{
_outputWriter.WriteLine("StopAsync");
}
protected void DoOperation(int opCode, int operand)
{
_outputWriter.WriteLine("Doing {0} to {1}...", opCode, operand);
// Do work that might take awhile
}
}
}
这段代码编译和运行都没有问题,会输出以下内容:Starting work
Doing 1 to 2...
Work complete
然而,在此之后,应用程序将一直等待,直到我按下Ctrl+C。我知道在工作完成后可以强制关闭应用程序,但此时,我觉得我没有正确使用IHostedService。它似乎是为定期后台进程而设计的,而不是像这样简单的控制台应用程序。然而,在实际应用程序中,DoOperation可能需要20-30分钟,我希望在终止之前利用StopAsync方法进行清理。我也知道我可以自己创建服务容器等所有内容,但.NET Core通用主机已经做了很多我想要做的事情。它似乎是编写控制台应用程序的正确方式,但如果没有添加启动实际工作的托管服务,那么如何让应用程序真正执行任何操作呢?
ServiceCollection
呢? - ProgrammingLlama