簡體   English   中英

.NET 5 WindowsService with ASP.NET Core and BackgroundService

[英].NET 5 WindowsService with ASP.NET Core and BackgroundService

我是新來的,也是 .NET 5 的新手,我真的被我的問題困住了。 我有一個 .NET 5 應用程序,它應該作為 Windows 服務執行,並且有一個 ASP.NET 核心(Kestrel?)REST 服務和一些 BackgroundService。 BackgroundService 是對某些服務器的某種輪詢服務,而 REST 服務旨在將已處理的輪詢結果檢索到某些 web 應用程序。

從命令行啟動時一切正常,但是當作為 Windows 服務部署和啟動時,它會在幾秒鍾后意外結束。

問題只出現,如果ASP.NET核心REST服務被激活,如果我的BackgroundService單獨執行,它也作為Windows服務工作。 ASP.NET 核心 REST 服務(沒有 BackgroundService)單獨也不能作為 Windows 服務工作 - 所以可能只是 ASP.NET 核心 / Windows 服務啟動沒有正確實施。

這就是我所做的:

程序.cs:

public class Program
    {
        public static async Task<int> Main(string[] args)
        {
            await CreateHostBuilder(args).Build().RunAsync();
            return 0;
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            var config = new ConfigurationBuilder()
                .SetBasePath(directoryName)
                .AddJsonFile(Path.Combine(directoryName, "appsettings.json"), false, true)
                .AddJsonFile(Path.Combine(directoryName, "appsettings.custom.json"), true, true)
                .AddCommandLine(args)
                .Build();

            return Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseUrls(baseUrl);
                    webBuilder.UseKestrel();
                    webBuilder.UseStartup<Startup>();
                })
                .UseWindowsService(options => options.ServiceName = "MyService");
            
        }
    }

我的啟動代碼:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;          
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            try
            {
                services.AddHostedService<MyBackgroundService>(provider =>
                    new MyBackgroundService(loggerForMyBackgroundService, configuration))
                        .Configure<EventLogSettings>(config =>
                        {
                            config.LogName = "MyService";
                            config.SourceName = "MyService";
                        });
            }
            catch (Exception ex)
            {
                logger.LogError($"Error during startup: {ex.Message}");
                throw;
            }

            services.AddCors();
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            
            app.UseCors(x => x
                .AllowAnyMethod()
                .AllowAnyHeader()
                .SetIsOriginAllowed(origin => true)
                .AllowCredentials());
            app.UseAuthorization();
            
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

我不確定是否缺少某些東西。 還是只是將所有內容按正確順序排列的問題? 是否可以在一個 Windows 服務中托管 BackgroundService 和 ASP.NET Core REST 服務?

非常感謝您的幫助。

最好的問候,卡斯滕

好的,我發現了問題。 使用 Debugger.Launch() 啟動 Windows 服務器並在 Visual Studio 中啟用所有異常最終導致異常消息:

無法配置 HTTPS 終結點。 未指定服務器證書,並且找不到默認的開發人員證書或已過期。 要生成開發人員證書,請運行“do.net dev-certs https”。 要信任證書(僅限 Windows 和 macOS)運行“do.net dev-certs https --trust”。

所以是的,它與環境有關 - 謝謝@jdweng,Windows 服務似乎無法獲得 web 開發默認證書。 所以我會為我的服務使用自己的專用證書。

最好將 main 方法包裝在 try catch 塊中,並將 output 寫入事件日志以查看此類錯誤,如下所示:

public static int Main(string[] args)
{
    
    try
    {
        CreateHostBuilder(args).Build().Run();
        return 0;
    }
    catch (Exception e)
    {
        var loggerFactory = LoggerFactory.Create(builder =>
        {
            SerilogLoggingBuilderExtensions.AddSerilog(
                 builder.AddFilter("Microsoft", LogLevel.Warning)
                        .AddFilter("System", LogLevel.Warning)
                        .AddFilter("MyNamespace", LogLevel.Debug)
                        .AddEventLog()
                        .AddConsole());
        });
        ILogger logger = loggerFactory.CreateLogger(typeof(Program)); 
        logger.LogError(e.Message);
        return -1;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM