坑爹!千万不要在生产环境使用控制台日志

前言

某控制台应用程序会随机卡死,一直找不到原因。无意中在控制台敲了下回车,发现程序居然恢复正常了。

e1c4f6f7a9b0dcf4c26be369720cb14a.gif

最后在stackoverflow上找到了这个帖子:How and why does QuickEdit mode in Command Prompt freeze applications?[1]

原来是“快速编辑模式”造成的。

快速编辑模式

快速编辑模式是Windows的一项功能,它允许用户在命令提示符窗口中使用鼠标选择文本(单击并在所需文本上拖动鼠标)。默认情况下此功能是开启的:

242f7f4adc9cb85f675578bc8302423b.png

不知是何原因,应用程序所在控制台接收到了鼠标事件,导致进入快速编辑模式,等待我们确定选中文本,而这时应用程序需要向控制台输出日志,结果导致死锁。

所以解决方案是关闭快速编辑模式。

关闭快速编辑模式

可以在“控制台窗口 属性”中设置默认值,取消“快速编辑模式”选项。

但是,为了避免部署时疏漏,使用代码自动禁用应用程序的快速编辑:

const uint ENABLE_QUICK_EDIT = 0x0040;

const int STD_INPUT_HANDLE = -10;

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll")]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);

[DllImport("kernel32.dll")]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

public static void Main(string[] args)
{
    IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);

    uint consoleMode;
    GetConsoleMode(consoleHandle, out consoleMode);

    consoleMode &= ~ENABLE_QUICK_EDIT;

    SetConsoleMode(consoleHandle, consoleMode);

    ...
}

关闭控制台日志

在生产环境,很少需要查看控制台日志。因此,更好的方式是关闭控制台日志,这样对程序性能也有一定好处。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureLogging(config =>
            {
                //清空默认配置
                config.ClearProviders();

                //使用第三方log
            });
            webBuilder.UseStartup<Startup>();
        });

结论

本文的情况你可能永远不会碰到,但是对于这种隐患,建议你不要在生产环境使用控制台日志。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

参考资料

[1]

How and why does QuickEdit mode in Command Prompt freeze applications?: https://stackoverflow.com/questions/30418886/how-and-why-does-quickedit-mode-in-command-prompt-freeze-applications

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值