c# - 在 C# 中使用 DI 登录到控制台
问题描述
在这个简短的示例中,如果我只保留任何内容,则无论 LogLevel 如何都不会记录到控制台,但是如果我添加.AddConsole()
所有消息,则会将所有消息记录到控制台 3 次!我错过了什么?谢谢!ConfigureServices
.AddConsole().AddDebug()
namespace samples
{
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
public class Program
{
public static void Main(string[] args)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
var app = serviceProvider.GetService<Application>();
app.Run();
}
private static void ConfigureServices(IServiceCollection services)
{
// Add Logger
services.AddLogging(configure => configure.AddConsole().AddDebug());
// Register Application
services.AddTransient<Application>();
}
}
public class Application {
private readonly ILogger logger;
public Application(ILogger<Application> logger)
{
this.logger = logger;
this.logger.LogInformation("In Application::ctor");
}
public void Run()
{
this.logger.LogInformation("Info: In Application::Run");
this.logger.LogWarning("Warn: In Application::Run");
this.logger.LogError("Error: In Application::Run");
this.logger.LogCritical("Critical: In Application::Run");
}
}
}
这就是每个 Log*() 调用所显示的内容:
fail: samples.Application[0]
Error: In Application::Run
samples.Application: Error: Error: In Application::Run
更新/解决方案
感谢@panoskarajohn 解决这个问题。App.Run() 需要是异步的:更改app.Run(); => Task.Run(() => app.Run()).Wait();
public void Run() => public async Task Run()
并且应该在没有调试()选项的情况下工作我找不到任何关于为什么会发生这种情况的信息
有谁知道为什么?
解决方案
我不知道为什么该
addDebug()
选项没有发生这种情况。
我想它AddDebug()
有一些特殊的配置,并在程序退出之前刷新输出。如有线索请赐教。
为什么 addConsole() 不起作用?
控制台日志记录发生在后台线程上。因此,如果应用程序退出太快,那么记录器就没有时间记录 -> https://github.com/aspnet/Logging/issues/631
所以这并不是没有发生。这是它没有时间写入控制台。应用程序退出太快。
为了在您的代码中解决此问题。在程序末尾添加 aConsole.Read()
以使其不会退出。
public static void Main(string[] args)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
var app = serviceProvider.GetService<Application>();
app.Run();
Console.Read(); // So the application will not exit and there will be time for the background thread to do its job
}
我还遇到了另一个解决方案,它是创建一个异步
Task
并等待它。
像这样更新代码。
public static void Main(string[] args)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
var app = serviceProvider.GetService<Application>();
Task.Run(() => app.Run()).Wait();
}
// also update your Application run method
public async Task Run()
{
logger.LogInformation("Info: In Application::Run");
logger.LogWarning("Warn: In Application::Run");
logger.LogError("Error: In Application::Run");
logger.LogCritical("Critical: In Application::Run");
}
最终结果应该是这样的。
public class Program
{
public static void Main(string[] args)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
var app = serviceProvider.GetService<Application>();
Task.Run(() => app.Run()).Wait();
Console.Read();
}
private static void ConfigureServices(IServiceCollection services)
{
// Add Logger
services.AddLogging(configure =>
{
configure.AddConsole();
}).AddTransient<Application>();
}
}
public class Application
{
private readonly ILogger<Application> logger;
public Application(ILogger<Application> logger)
{
this.logger = logger;
this.logger.LogInformation("In Application::ctor");
}
public async Task Run()
{
logger.LogInformation("Info: In Application::Run");
logger.LogWarning("Warn: In Application::Run");
logger.LogError("Error: In Application::Run");
logger.LogCritical("Critical: In Application::Run");
}
//public void Run()
//{
// logger.LogInformation("Info: In Application::Run");
// logger.LogWarning("Warn: In Application::Run");
// logger.LogError("Error: In Application::Run");
// logger.LogCritical("Critical: In Application::Run");
//}
}
推荐阅读
- questdb - 通过 SQL 插入记录时遇到错误代码 00000
- c# - 绑定从方法获得的属性,返回对象
- azure - 如何追溯标记 Azure 资源?
- mongodb - 如何在一个 MongoDB 查询中加入两个集合
- reactjs - React js select不将文本显示为值
- sql - 同时选择和更新行
- python - 如何在 Gurobipy 中定义与二维矩阵相乘的目标函数
- string - LateInitializationError:本地“newTaskTitle”尚未初始化。(如果我最小化键盘,它不会添加新任务?)
- html - 角 | SwiperJS 分页和导航按钮不起作用
- java - 从字符串中删除元音,除非元音使用 for 循环开始单词