gpt4 book ai didi

c# - Console.ReadKey 与带有计时器的 Console.ReadLine

转载 作者:可可西里 更新时间:2023-11-01 08:10:21 32 4
gpt4 key购买 nike

以下代码是一个众所周知的示例,用于显示调试版本和发布版本之间的区别:

using System;
using System.Threading;

public static class Program
{
public static void Main()
{
Timer t = new Timer(TimerCallback, null, 0, 2000);
Console.ReadLine();
}

private static void TimerCallback(Object o)
{
Console.WriteLine("In TimerCallback: " + DateTime.Now);
GC.Collect();
}
}

如果您使用调试配置运行它,计时器将每两秒输出一次当前时间。 GC.Collect 没有任何效果,因为编译器人为地延长了 Timer t 变量的生命周期。在发布配置中,计时器将只执行一次。 GC.Collect 将垃圾收集 t 变量,仅此而已。

一切正常。奇怪的是,当您将 Console.ReadLine 行更改为 Console.ReadKey both 配置时,每两秒运行一次计时器。

Console.ReadKey 和 Console.ReadLine 有什么区别?我明白了from the documentation Console.ReadKey 阻止发出 ReadKey 方法的线程。但是 GC.Collect 仍然会触发......

为什么通过阻塞主线程来延长Timer t的生​​命周期?

更新

使用 .NET 3.5 时,不会发生此行为!

最佳答案

Console.ReadKey() 方法锁定了 Console.InternalSyncObjectConsole.ReadLine() 方法则没有。当 TimerCallBack() 方法试图写入 Console 时,Thread 等待,因为 Console.InternalSyncObject 仍然锁定。因此 GC.Collect() 永远不会被调用。只要您按下一个键,锁就会被释放,GC.Collect() 就会被调用。

我将您的代码更改为以下代码,它不会锁定 Console.InternalSyncObject,它只会在 Release 中发出一次蜂鸣声,在 Debug 中每 2 秒发出一次蜂鸣声。

private static void TimerCallback(Object o)
{
Console.Beep();
GC.Collect();
}

Console.WriteLine() 等待的原因是因为它在创建 Console.Out TextWriter< 时试图获取 Console.InternalSyncObject 上的锁 第一次。

将您的代码更改为以下内容会按预期工作,因为我们会在启动计时器之前创建 Console.Out TextWriter

public static void Main()
{
Console.WriteLine("Loaded");
Timer t = new Timer(TimerCallback, null, 0, 2000);
Console.ReadKey();
}

private static void TimerCallback(Object o)
{
Console.WriteLine("In TimerCallback: " + DateTime.Now);
GC.Collect();
}

这是由于 .NET 4.5 中的更改。更多信息 here

关于c# - Console.ReadKey 与带有计时器的 Console.ReadLine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15679683/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com