【问题标题】:Running ASP.NET Core on Worker Service in .NET 3.0在 .NET 3.0 中的 Worker 服务上运行 ASP.NET Core
【发布时间】:2020-02-29 12:22:51
【问题描述】:

我已经设法构建了一个 Worker Service,并将 ASP.NET Core API 添加到该服务中,该服务运行良好。我面临的问题是将其安装为 Windows 服务。自从升级到 .NET 3.0 以来,发生了很多重大变化,尤其是 HostBuilder

下面是我的Program class

 public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
            CreateWebHostBuilder(args).Build().Run();
        }

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureServices((hostcontext, svc) =>
            {
                svc.AddHostedService<Worker>();
            });

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseKestrel((context, serverOptions) =>
                {
                    serverOptions.ListenAnyIP(1044);
                    serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(1.5);
                });

当我像这样运行它时,它无法选择 WebHost 构建器,而当我只使用 WebHost 构建器运行时,它无法在目标服务器上安装服务。

请协助我想利用IWebHostBuilderIHostBuilder 的优点,但我不知道如何在static main 方法中组合它们。

以下是其他文件;

StartUp

 public void ConfigureServices(Microsoft.Extensions.DependencyInjection.IServiceCollection services)
        {
            services.AddHostedService<Worker>();

            ////Add Controllers
            //services.AddTransient<SalesForceDataLoaderController>();


            //Add DB Dependency Injection
            services.AddAutoMapper(typeof(Startup));

            services.AddMvc().AddJsonOptions(options =>
            {
                options.UseCamelCasing(true);
            }).AddControllersAsServices();
            services.AddDbContext<SalesForceReportLoaderContext>(options =>
                options.UseSqlServer(this.APIdb));

            services.AddScoped<IRepositoryWrapper, RepositoryWrapper>();
            services.AddScoped<ILogger, Logger<SalesForceDataLoaderController>>();
            services.AddScoped<ILogger, Logger<ActisureWhatsAppController>>();
            services.AddScoped<ILogger, Logger<PureWhatsAppController>>();

            services.AddSingleton(typeof(IRepository<>), typeof(Repository<>));
            services.AddSingleton<ISalesforceLoaderRepository, SalesforceLoaderRepository>();
            services.AddSingleton<IActWhatsAppClaimStatusRepo, ActWhatsAppClaimStatusRepo>();
            services.AddSingleton<IPureWhatsAppClaimStatusRepo, PureWhatsAppClaimStatusRepo>();
            services.AddSingleton<IPureWhatsAppPolicyDetailsRepo, PureWhatsAppPolicyDetailsRepo>();


        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseMvc();
            //app.UseRouting();

        }

还有我的worker class

 public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        public override Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Service Starting at: {time}", DateTimeOffset.Now);
            return base.StartAsync(cancellationToken);
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    //Run a request

                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.InnerException.ToString());
                }

                _logger.LogInformation("Salesforce Service running at: {time}", DateTimeOffset.Now);
                await Task.Delay(2500, stoppingToken);
            }
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Service Stop at: {time}", DateTimeOffset.Now);
            return base.StopAsync(cancellationToken);
        }

        public override void Dispose()
        {
            _logger.LogInformation("Resources released at: {time}", DateTimeOffset.Now);
            base.Dispose();
        }
    }

编辑

我现在已经正常使用svc 安装了该服务,但我不断收到此错误

[SC] StartService FAILED 1053:

The service did not respond to the start or control request in a timely fashion.

【问题讨论】:

  • 错误消息会很有用。 Directory.GetCurrentDirectory() 是什么?如果它是一个配置文件目录(`C:\Users\xxx\yyy`)那么它就无法工作,Windows 服务通常在没有配置文件的情况下运行(例如网络服务组)
  • 我已经尝试过了,但在尝试启动服务时出现此错误[SC] StartService FAILED 1053: The service did not respond to the start or control request in a timely fashion.
  • 我更多的意思是来自您的 .NET Core 应用程序的错误消息
  • 应用程序在调试模式下运行正常,我怀疑部署时出现的错误是 [SC] StartService FAILED 1053: 是由于 WebHostBuilder 中缺少 UseWindowService 注入
  • 这是真的吗?

标签: c# asp.net-core .net-core-3.0


【解决方案1】:

我设法解决了这个问题并在我的机器上本地部署了服务;原来包裹是分开的; Microsoft.AspNetCore.Hosting.WindowsServicesMicrosoft.Extensions.Hosting.WindowsServices

所以我所要做的就是添加包并重构program.cs,如下所示;

public static void Main(string[] args)
        {

            CreateWebHostBuilder(args).Build().RunAsService();

        }

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseContentRoot(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName))
                .UseStartup<Startup>()
                .UseKestrel((context, serverOptions) =>
                {
                    serverOptions.ListenAnyIP(1044);
                    serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(1.5);
                });

有关更多上下文,请参阅link

【讨论】:

  • 您也可以解决在发布配置文件中添加自包含方法的问题,感谢您提供的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-02
相关资源
最近更新 更多