当静态变量在方法中枚举时设置为null时会发生什么

Dan*_*nds 1 c# multithreading

给定以下类并假设打印列表需要很长时间才能运行,如果线程1调用PrintList()然后在它运行时会发生什么,线程2会调用ClearList?

我们不是修改集合只是将引用更改为指向堆中不同位置的点.那么枚举继续有效吗?如果是这样,因为_someList引用的副本放在方法的堆栈帧上?

public class foo()
{

    private static List<string> _someList;

    public void ClearList()
    {
        _someList = null;
    }

    public void PrintList()
    {
        foreach(var item in _someList)
        {
            Console.Print(item);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Ser*_*rvy 6

两个非常可预测的事情之一将会发生.在某个时间点,第一个线程将评估变量_someList值到其值,即对列表的引用.如果在第二个线程清除它之前发生这种情况,那么它将遍历该列表并打印结果.如果第二个线程在它到达foreach循环之前碰巧清除了列表,那么你将得到一个空引用异常.

请注意,对引用类型的变量的读取和写入是可观察的原子,因此我们知道将变量设置为null不会导致无效引用; 第一个线程将观察原始引用,或者null没有"读取垃圾引用"的可能性.