Приставка.ReadKey против консоли.С readline с таймером
следующий код является хорошо известным примером, чтобы показать разницу между сборкой отладки и выпуска:
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();
}
}
если вы запустите это с отладочной конфигурации, таймер будет выводить текущее время каждые две секунды. The GC.Collect
не имеет никакого эффекта, потому что компилятор искусственно продлевает жизнь Timer t
переменной. В конфигурации release, таймер будет выполняться только один раз. The GC.Collect
будет мусор собирать t
переменная, и это он.
все это работает так, как должно. Странная вещь, когда вы меняете консоль line.ReadLine для консоли.ReadKey и настройки запуска по таймеру каждые две секунды.
в чем разница между консолью.ReadKey и консоль.С readline? Я понял!--15-->из документации этой консоли.ReadKey блокирует поток, выдающий метод ReadKey. Но GC.Собирайте еще пожары..
почему в жизни Timer t
extended, блокируя основной поток?
обновление
при использовании .NET 3.5 это поведение не произойдет!
1 ответов
на Console.ReadKey()
способ блокировки Console.InternalSyncObject
а Console.ReadLine()
метод не. Когда TimerCallBack()
метод пытается написать Console
на Thread
ждет, потому что Console.InternalSyncObject
все еще заблокирован. Поэтому GC.Collect()
никогда не вызывается. Как только вы нажмете клавишу блокировки и GC.Collect()
называется.
я изменил ваш код на следующий, который не блокирует Console.InternalSyncObject
и он подает звуковой сигнал только один раз в выпуске и каждые 2 секунды в отладке.
private static void TimerCallback(Object o)
{
Console.Beep();
GC.Collect();
}
причина пульт.Метода WriteLine() ждет, потому что он пытается получить блокировку на Console.InternalSyncObject
при создании Console.Out
TextWriter
впервые.
изменение кода на следующие работы, как и ожидалось, когда мы создаем 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. Подробнее здесь