C# System.Threading.Timer的奇怪行为
我试图了解定时器将如何使用线程池。我写了下面这个简单的片段C# System.Threading.Timer的奇怪行为,c#,multithreading,timer,interlocked,interlocked-increment,C#,Multithreading,Timer,Interlocked,Interlocked Increment,我试图了解定时器将如何使用线程池。我写了下面这个简单的片段 class Program { static private readonly Action Action = () => { Thread.SpinWait(100 * 10000); Inter
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();
}
}
类程序
{
静态私有只读操作操作=()=>{
线程。自旋等待(100*10000);
联锁增量(参考数据);
};
私有静态易失性int_数据;
静态专用计时器_threadCountChecker=新计时器(
(obj)=>
{
var t=Process.GetCurrentProcess()线程;
WriteLine(“使用{0}个线程。”,t.Count);
控制台写入线(程序数据);
},null,TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(1));
静态void Main(字符串[]参数)
{
var l=新列表();
对于(int i=0;i<10;i++)
{
l、 添加(新计时器((obj)=>Action(),null,TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(1));
}
var exitEvent=新手动重置事件(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
有人知道为什么变量在前8次迭代中被更新,而只是停止递增吗?计时器被垃圾收集。在eventWait.WaitOne()调用后添加此语句以修复以下问题:
GC.KeepAlive(l);
GC在发布版本中处理局部变量的方式将在中详细解释。计时器被垃圾收集。在eventWait.WaitOne()调用后添加此语句以修复以下问题:
GC.KeepAlive(l);
GC在发布版本中处理局部变量的方式将在中详细说明