[英]How to prevent .net 6 generic hosted console apps logging queue from being shutdown on application stop?
我目前正在為 do.net 控制台應用程序開發一個小型演示項目,使用通用托管進行日志記錄和配置。 在編寫這個演示/概念驗證應用程序的上下文中,我遇到了一個問題,控制台的日志消息停止寫入,但程序本身沒有問題地完成了他的工作。
這里的控制台應用程序應該進行批處理,而不是作為一個長期運行的服務。 我們打算找出是否(以及如何)以並行方式處理這些項目。 因此我們創建了這個演示程序。 在這個演示程序中,我們特意決定不使用異步調用。 首先,使其盡可能線性,其次,使其盡可能易於理解。 在即將到來的迭代中,我們將添加/刪除此類功能,具體取決於我們探索的路徑和運行時行為。
這是我第一次體驗 do.net 6(+) 中的通用托管。 我想受益於 DI、配置和日志記錄等開箱即用的功能。
現在我的問題:
IHostedService
是正確的方法嗎? 我應該使用BackgroundService
嗎?console logger queue
完成其工作?這是非常簡化的設置:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
})
.ConfigureServices((_, services) =>
{
services.AddHostedService<Worker>();
})
.Build();
host.Start();
// host.Run(); // could be used instead of host.Start();
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
internal class Worker : IHostedService
{
private readonly ILogger<Worker> _log;
private readonly IHostApplicationLifetime _appLifetime;
public Worker2(ILogger<Worker> log,
IHostApplicationLifetime appLifetime
) => (_log, _appLifetime) = (log, appLifetime);
public Task StartAsync(CancellationToken cancellationToken)
{
_log.LogInformation("now load a list of item numbers");
var itemNumbers = Enumerable.Range(1, 1000);
foreach (var itemNumber in itemNumbers)
{
if (cancellationToken.IsCancellationRequested)
break;
_log.LogInformation("processing item nr {itemNumber}", itemNumber);
}
_log.LogInformation("I'm done here. good bye!");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
info: Worker2[0]
now load a list of item numbers
info: Worker2[0]
processing item nr 1
info: Worker2[0]
processing item nr 2
info: Worker2[0]
processing item nr 3
...
info: Worker2[0]
processing item nr 22
info: Worker2[0]
processing item nr 23
info: Worker2[0]
processing item nr 24
Process finished with exit code 0.
調試這個簡單的應用程序時,它顯示它實際上運行了所有 1000 個項目,並且還記錄了最后一條消息(“我在這里完成了。再見。”),不幸的是。 來自項目 nr 的日志。 25 及以上永遠不會寫入控制台。
我發現了什么:
worker
線程,一個用於console logger queue
。console logger queue
線程worker
(或它完成),它會關閉應用程序,並且應用程序不會等待console logger queue
(因此會殺死它)。BackgroundService
給我相同的結果。host.Run()
而不是host.Start()
確實有效,盡管我必須手動停止應用程序,這也不是我想要的。 當它完成它的工作時,它應該終止。先感謝您!
我會將 app.Start 包裝在 try/catch/finally 中……並根據您是否使用 Serilog 之類的東西……在最后調用 Log.CloseAndFlush()。
此處類似的問題: How can I flush all loggers in a do.net core appliation just before doing a Environment.Exit()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.