The quot;correctquot; way to create a .NET Core console app without background services(创建没有后台服务的.NET核心控制台应用程序的正确方法)
问题描述
我正在构建一个简单的.NET Core控制台应用程序,它将从命令行读取基本选项,然后在没有用户交互的情况下执行和终止。我想利用DI,这样我就可以使用.NET Core泛型主机。我发现的构建控制台应用程序的所有示例都创建了一个实现IHostedService或扩展Backround Service的类。然后通过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; }
    }
}
MyService.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泛型主机已经做了很多我无论如何都想做的事情。似乎是编写控制台应用程序的正确方式,但是在不添加开始实际工作的托管服务的情况下,如何让应用程序实际执行任何操作?
推荐答案
代替托管服务,我建议使用以下服务;
using (var host = CreateHostBuilder(args).Build())
{
    await host.StartAsync();
    var lifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
    // do work here / get your work service ...
    lifetime.StopApplication();
    await host.WaitForShutdownAsync();
}
                        这篇关于创建没有后台服务的.NET核心控制台应用程序的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:创建没有后台服务的.NET核心控制台应用程序的正确方法
				
        
 
            
        - 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
 - 如何用自己压缩一个 IEnumerable 2022-01-01
 - WebMatrix WebSecurity PasswordSalt 2022-01-01
 - 输入按键事件处理程序 2022-01-01
 - 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
 - MoreLinq maxBy vs LINQ max + where 2022-01-01
 - Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01
 - C# 中多线程网络服务器的模式 2022-01-01
 - 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
 - C#MongoDB使用Builders查找派生对象 2022-09-04
 
						
						
						
						
						
				
				
				
				