我一直在玩下面的代码:
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;
}
}
虽然 main 的第一部分执行顺利,但当我注释对Thread.Sleep()
方法的调用时,第二部分失败,我得到一个空异常。
我的理解是 lambda 表达式被延迟评估,可能会发生新线程启动速度不够快并且主线程设置r
为null
第一个的情况。r
现在我把这个“第二部分”放在一个具有本地范围的静态方法中,问题就消失了。但是我想知道在这种特殊情况下线程调度程序是否隐藏了问题,也许在具有不同工作负载的不同机器上仍然可能发生。或者关于 lambda 表达式是否有一些东西可以保证即使r
超出范围,只要它没有被设置为null
,它仍然以某种方式被引用。
最终我想知道我是否应该考虑ParameterizedThreadStart
尽可能多地使用委托或坚持使用 lambda,因为我尊重某些条件以保持它们有效。