我一直在玩弄下面的一段代码:ParameterizedThreadStart是否保证对象实例不会被垃圾收集?
class RunMeBaby
{
public void Start()
{
while (true)
{
Console.WriteLine("I'm " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
}
}
}
class Program
{
static void Main(string[] args)
{
RunMeBaby r = new RunMeBaby();
Thread t = new Thread(r.Start); // ParameterizedThreadStart delegate
r = null;
GC.Collect(GC.MaxGeneration);
t.Start();
r = new RunMeBaby();
t = new Thread(() => r.Start()); // ThreadStart delegate
t.Start();
//Thread.Sleep(1000);
r = null;
}
}
虽然主要在第一部分顺利执行,当我评论的调用Thread.Sleep()
方法的第二部分失败,我得到一个空例外。
我的理解是lambda表达式被懒惰地评估,可能会发生新线程启动不够快,主线程首先设置r
到null
。现在我把这个“第二部分”放在一个静态方法中,r
有一个局部范围,问题就消失了。但是我想知道在这种特殊情况下线程调度程序是否隐藏了问题,也许在不同的机器上可能会发生不同的工作负载。或者是否有关于lambda表达式的内容可以保证即使r
超出范围,只要它未被设置为null
,它仍以某种方式被引用。
最终我不知道是否应该考虑尽可能多地使用ParameterizedThreadStart
委托人,或者坚持使用lambda表达式,因为我尊重某些条件以保持其有效性。