我想了解一下Timer如何使用线程池。我写了以下简单的片段。
class Program
{
static private readonly Action Action = () => {
Thread.SpinWait(100 * 10000);
Interlocked.Increment(ref _data);
};
private static volatile int _data;
static private Timer _threadCountChecker = new Timer(
(obj) =>
{
var t = Process.GetCurrentProcess().Threads;
Console.WriteLine("Using {0} threads.", t.Count);
Console.WriteLine(Program._data);
}, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
static void Main(string[] args)
{
var l = new List<Timer>();
for (int i = 0; i < 10; i++)
{
l.Add(new Timer((obj) => Action(), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)));
}
var exitEvent = new ManualResetEvent(false);
exitEvent.WaitOne();
}
}
令人惊讶的是,这是我得到的输出:
使用14个线程。 10使用14个线程。 18使用14个线程。 28使用 14个主题。 39使用14个线程。 48使用15个线程。 58使用15 线程。 69使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80使用15个线程。 80使用15 线程。 80使用15个线程。 80
无论我持续运行多长时间,数据变量都保持在80.
有没有人知道为什么变量在前8次迭代中得到更新并且只是停止递增?
答案 0 :(得分:5)
计时员收集了垃圾。在eventWait.WaitOne()调用之后添加此语句来修复:
GC.KeepAlive(l);
在this answer中详细介绍了GC处理Release版本中局部变量的方式。