我的 .NET 5 WebApp 作為 Windows 服務運行,并在啟動期間使用物體框架來播種和更新(遷移)其資料庫。在呼叫之前Host.Run(),我確保我的資料庫已更新。這在過去的一年里運行得非常好。現在,我有一個需要幾分鐘才能完成的大型資料庫更新。在此資料庫更新期間,Windows 服務將關閉并顯示錯誤 1053,表示超時。我懷疑這是由于運行時Host.Run()在給定的默認超時時間(看起來大約 30 秒)內沒有達到呼叫。問題是我必須在呼叫之前執行這些資料庫更新Host.Run(),因為在對其進行任何訪問之前應該正確更新資料庫。
這個問題最簡單的解決方案是什么?我可以嘗試撰寫自定義服務生命周期來增加超時。我可以移動要執行的資料庫更新,并在執行Host.Run()時限制訪問的額外開銷。我還不喜歡這些解決方案中的任何一個,并尋求更好的選擇。也許我的假設也完全錯誤。我的代碼在下面提供。
public class Program
{
public static async Task Main(string[] args)
{
IHost host = CreateHostBuilder(args).Build();
using (IServiceScope scope = host.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
SeedAndUpdateDb seed = services.GetRequiredService<SeedAndUpdateDb>();
await seed.InitializeAsync(); //<- This call takes a few minutes to complete
}
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
var hostingConfig = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel(serverOptions =>
{
serverOptions.Configure(hostingConfig.GetSection("Kestrel"));
});
webBuilder.UseKestrel(options =>
{ });
});
}
}
uj5u.com熱心網友回復:
底線是:如果您正在運行的可執行檔案要被識別為已啟動的 Windows 服務,則它必須(在作為服務安裝并啟動后)在服務啟動時告訴Windows 服務控制管理器它實際上是一個服務并且它已成功啟動。
如果它沒有及時啟動,您會收到可怕的錯誤訊息,即服務沒有及時啟動。
您.UseWindowsService()對 SCM 的呼叫設定了所有管道,但對 SCM 的呼叫僅在 .NET Core 主機啟動代碼中進行await host.RunAsync()。
因此,如果在您的可執行檔案啟動(由于您啟動服務)和您的代碼呼叫之間await host.RunAsync()經過了太多時間,您的可執行檔案將運行并且您的托管服務最終將運行,但就 Windows 而言,您的Windows 服務沒有啟動(及時)。
解決方案是使用命令列標志呼叫遷移,而不是在每次啟動時呼叫。或者在您的托管服務中呼叫一次遷移,因此當 Windows 服務已經在運行時。
對于命令列方法:因此在部署之后,您可以Your-Service.exe --migrate在啟動 Windows 服務之前運行。
像這樣的東西:
public static async Task Main(string[] args)
{
IHost host = CreateHostBuilder(args).Build();
if (args.Any(a => a == "--migrate"))
{
using (IServiceScope scope = host.Services.CreateScope())
{
IServiceProvider services = scope.ServiceProvider;
SeedAndUpdateDb seed = services.GetRequiredService<SeedAndUpdateDb>();
await seed.InitializeAsync(); //<- This call takes a few minutes to complete
}
Console.WriteLine("Database migrated, you can now start the service");
}
else
{
await host.RunAsync();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/381542.html
