【问题标题】:Can't start worker service as windows service无法将工作服务作为 Windows 服务启动
【发布时间】:2022-04-27 02:48:06
【问题描述】:

所以。我创建了一个工作服务并希望将其作为 Windows 服务运行。它在本地工作。我通过 powershell new-service 命令将它安装到 Windows 服务器。当我通过服务启动它时,它会尝试启动,等待 30 秒(加载栏正在进行)并失败。在事件查看器中,我看到一般错误:

  1. 等待 MyService 服务连接时超时(30000 毫秒)。
  2. MyService 服务因以下错误无法启动: 服务未及时响应启动或控制请求。

现在,奇怪的是,我在服务逻辑中添加了一些日志记录,它实际上确实需要一些东西,windows 只是无法启动它,即服务没有响应启动,但工作(30 秒,在那台服务器之后杀死它,因为它没有响应开始)。 我如何解决它? 我的 Program.cs:

    public class Program
{
    public static void Main(string[] args)
    {
        try
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            File.AppendAllText("templogs.txt", ex.Message + "\r\n");
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureServices((hostContext, services) =>
            {
                IConfiguration configuration = hostContext.Configuration;
                services.AddHostedService<Worker>();
                services.AddScoped<IActionHandler, ActionHandler>();
                services.AddScoped<IHttpHandler, HttpHandler>();
                services.AddDbContext<DbContext>(options =>
                {
                    options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
                });
                File.AppendAllText("templogs.txt", "context registered\r\n");

            });
}

工人服务:

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly List<string> _inactiveStatuses;
    private readonly IServiceProvider _services;
    private readonly string _connectionString;


    public Worker(ILogger<Worker> logger, IConfiguration config, IServiceProvider services)
    {
        try
        {
            _logger = logger;
            _inactiveStatuses = config.GetSection("InactiveStatuses").GetChildren().Select(a => a.Value).ToList();
            _services = services;
            _connectionString = config.GetConnectionString("DefaultConnection");
        }
        catch (Exception ex)
        {
            File.AppendAllText("templogs.txt", ex.Message + "\r\n");
        }
    }
    public override async Task StartAsync(CancellationToken cancellationToken)
    {
        await base.StartAsync(cancellationToken);
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        await base.StopAsync(cancellationToken);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            using (var scope = _services.CreateScope())
            {
                File.AppendAllText("templogs.txt", "scope created\r\n");

                var actionHandler =
               scope.ServiceProvider
                   .GetRequiredService<IActionHandler>();
                var dbContext = scope.ServiceProvider.GetRequiredService<DbContext>();
                var activeStatuses = dbContext.Statuses.Where(a => !_inactiveStatuses.Contains(a.Name)).ToDictionary(a => a.Id, a => a.Name);
                List<Guid> activeStatusGuids = activeStatuses.Keys.ToList();
                while (!stoppingToken.IsCancellationRequested)
                {
                    File.AppendAllText("templogs.txt", "while strated\r\n");
                    //some logic
                    File.AppendAllText("templogs.txt", "first cycle\r\n");

                    await Task.Delay(1000, stoppingToken);
                }
            }
        }
        catch (Exception ex)
        {
            File.AppendAllText("templogs.txt", ex.Message + "\r\n");
        }
    }
}

【问题讨论】:

  • 你确定你发布的代码有这个问题吗?
  • 是的,我确定。

标签: c# asp.net-core windows-services backgroundworker windows-server


【解决方案1】:

由于我不知道您用于创建 Windows 服务的 powershell new-service 命令,为了回答这个问题,我假设问题与我遇到的问题有关。

在我的例子中,我使用 Windows 命令提示符创建并启动了一个名为 Worker.Service 的服务。

这是我遇到The service did not respond to the start or control request in a timely fashion. 错误的方式:

sc create Worker.Service binPath="C:\Users\<user.name>\source\repos\<repo>\Worker.Service\bin\Debug\netcoreapp3.1\Worker.Service.dll"

sc start Worker.Service

下面是正确的启动方式:

sc create Worker.Service binPath="C:\Users\<user.name>\source\repos\<repo>\Worker.Service\bin\Debug\netcoreapp3.1\Worker.Service.exe"

sc start Worker.Service

binPath 可以通过 Visual Studio 的构建输出窗口获得。但是请确保您使用.exe 文件而不是.dll 文件来注册服务。

【讨论】:

    猜你喜欢
    • 2014-08-30
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 2017-09-09
    相关资源
    最近更新 更多