Kla*_*ark 1 c# multithreading timer interlocked interlocked-increment
我试图了解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();
}
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,这是我得到的输出:
使用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次迭代中得到更新并且只是停止递增?
计时器收集了垃圾.在eventWait.WaitOne()调用之后添加此语句来修复:
GC.KeepAlive(l);
Run Code Online (Sandbox Code Playgroud)
本回答详细介绍了GC处理Release版本中局部变量的方式.