【问题标题】:NetCore 2.1 Generic Host as a serviceNetCore 2.1 通用主机即服务
【发布时间】:2018-06-14 00:45:30
【问题描述】:

我正在尝试使用最新的 Dotnet Core 2.1 运行时构建 Windows 服务。我没有托管任何 aspnet,我不希望或不需要它来响应 http 请求。

我遵循了示例中的代码:https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/host/generic-host/samples/2.x/GenericHostSample

我也看过这篇文章:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1

代码在使用 dotnet run 在控制台窗口内运行时效果很好。我需要它作为 Windows 服务运行。我知道有 Microsoft.AspNetCore.Hosting.WindowsServices,但这是针对 WebHost,而不是通用主机。我们会使用 host.RunAsService() 作为服务运行,但我看不到它存在于任何地方。

如何将其配置为作为服务运行?

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace MyNamespace
{
    public class Program
    {


        public static async Task Main(string[] args)
        {
            try
            {
                var host = new HostBuilder()
                    .ConfigureHostConfiguration(configHost =>
                    {
                        configHost.SetBasePath(Directory.GetCurrentDirectory());
                        configHost.AddJsonFile("hostsettings.json", optional: true);
                        configHost.AddEnvironmentVariables(prefix: "ASPNETCORE_");
                        configHost.AddCommandLine(args);
                    })
                    .ConfigureAppConfiguration((hostContext, configApp) =>
                    {
                        configApp.AddJsonFile("appsettings.json", optional: true);
                        configApp.AddJsonFile(
                            $"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json",
                            optional: true);
                        configApp.AddEnvironmentVariables(prefix: "ASPNETCORE_");
                        configApp.AddCommandLine(args);
                    })
                    .ConfigureServices((hostContext, services) =>
                    {
                        services.AddLogging();
                        services.AddHostedService<TimedHostedService>();
                    })
                    .ConfigureLogging((hostContext, configLogging) =>
                    {
                        configLogging.AddConsole();
                        configLogging.AddDebug();

                    })

                    .Build();

                await host.RunAsync();
            }
            catch (Exception ex)
            {



            }
        }


    }

    #region snippet1
    internal class TimedHostedService : IHostedService, IDisposable
    {
        private readonly ILogger _logger;
        private Timer _timer;

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

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Background Service is starting.");

            _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromSeconds(5));

            return Task.CompletedTask;
        }

        private void DoWork(object state)
        {
            _logger.LogInformation("Timed Background Service is working.");
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Background Service is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }
    #endregion
}

编辑:我再说一遍,这不是托管 ASP.NET Core 应用程序。这是一个通用的主机构建器,而不是一个 WebHostBuilder。

【问题讨论】:

  • 不是骗子。那是用于托管 asp.net 核心。 WebHost.RunAsService。我没有使用 WebHost,我使用的是通用主机。
  • 再次查看主机构建器。它不是用于监听 http 请求的 WebHostBuilder。它是一个通用的 HostBuilder,只为运行后台任务而设计,它不监听 http 请求。必读:docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
  • 你找到解决这个问题的合适方法了吗?

标签: c# .net-core


【解决方案1】:

正如其他人所说,您只需要重用 IWebHost 接口的代码,这是一个示例。

public class GenericServiceHost : ServiceBase
{
    private IHost _host;
    private bool _stopRequestedByWindows;

    public GenericServiceHost(IHost host)
    {
        _host = host ?? throw new ArgumentNullException(nameof(host));
    }

    protected sealed override void OnStart(string[] args)
    {
        OnStarting(args);

        _host
            .Services
            .GetRequiredService<IApplicationLifetime>()
            .ApplicationStopped
            .Register(() =>
            {
                if (!_stopRequestedByWindows)
                {
                    Stop();
                }
            });

        _host.Start();

        OnStarted();
    }

    protected sealed override void OnStop()
    {
        _stopRequestedByWindows = true;
        OnStopping();
        try
        {
            _host.StopAsync().GetAwaiter().GetResult();
        }
        finally
        {
            _host.Dispose();
            OnStopped();
        }
    }

    protected virtual void OnStarting(string[] args) { }

    protected virtual void OnStarted() { }

    protected virtual void OnStopping() { }

    protected virtual void OnStopped() { }
}

public static class GenericHostWindowsServiceExtensions
{
    public static void RunAsService(this IHost host)
    {
        var hostService = new GenericServiceHost(host);
        ServiceBase.Run(hostService);
    }
}

【讨论】:

    【解决方案2】:

    我希望您找到了解决此问题的方法。

    在我的例子中,我使用通用主机(在 2.1 中引入)用于此目的,然后将其与 systemd 一起包装,以在 Linux 主机上将其作为服务运行。

    我写了一篇关于它的小文章https://dejanstojanovic.net/aspnet/2018/june/clean-service-stop-on-linux-with-net-core-21/

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      IHostedService 如果用于 [asp.net core] 后端作业, 如果你想在.net core 上构建一个windows 服务,你应该引用这个包System.ServiceProcess.ServiceController,并使用ServiceBase 作为基类。 (您也可以从 .net 框架 windows 服务启动,然后更改 .csproj 文件)


      编辑:请参阅this doc 和此代码https://github.com/aspnet/Hosting/blob/dev/src/Microsoft.AspNetCore.Hosting.WindowsServices/WebHostWindowsServiceExtensions.cs。 创建一个windows服务ServiceBase来管理你的IHost

      【讨论】:

      • 您在理解 IWebHost 和 IHost 之间的区别时也有问题。您提供的链接适用于 IWebHost。这个项目是针对 IHost 的,它不监听 http 请求。我不会使用 IWebHost,因为服务监听 http 请求是没有意义的。必读:docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
      • 是的,这个链接是给IWebHost的,但是和IHost几乎一样,我想告诉你的是如何在windows服务下运行它例如ServiceBase,这并不难要理解,RunAsService 扩展方法的作用是创建一个名为 WebHostService 的简单 ServiceBase 类来启动/停止 IWebHost(在您的情况下为 IHost)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 2019-05-30
      相关资源
      最近更新 更多