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

C# 当静态变量在方法中枚举时被设置为null时会发生什么,c#,multithreading,C#,Multithreading,给定以下类并假设print list需要很长时间才能运行,如果线程1调用print list,然后在运行时线程2调用ClearList,会发生什么情况 我们不是修改集合,只是将引用更改为指向堆中的不同位置。那么,枚举是否继续有效?如果是,这是因为将_someList引用的副本放在该方法的堆栈帧上吗 public class foo() { private static List<string> _someList; public void ClearList()

给定以下类并假设print list需要很长时间才能运行,如果线程1调用print list,然后在运行时线程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);
        }
    }

}

两件非常可预测的事情中的一件将会发生。在某个时间点,第一个线程会将varaible _someList计算为其值,即对列表的引用。如果这发生在第二个线程清除它之前,那么它将遍历该列表并打印结果。如果第二个线程在到达foreach循环之前恰好清除了列表,那么您将得到一个null引用异常


注意,对引用类型的变量的读写是可观察的原子,因此我们知道将变量设置为null不会导致无效引用;第一个线程要么观察原始引用,要么为null,不存在读取垃圾引用的可能性。

将发生两种非常可预测的情况之一。在某个时间点,第一个线程会将varaible _someList计算为其值,即对列表的引用。如果这发生在第二个线程清除它之前,那么它将遍历该列表并打印结果。如果第二个线程在到达foreach循环之前恰好清除了列表,那么您将得到一个null引用异常


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

即使枚举继续工作,依赖这种行为至少听起来很危险。如果您认为其他人正在使用某个变量,那么您的代码不应该将该变量设置为null。如果有您担心的情况,您应该具体处理它们。我同意这不是您希望在代码中执行的操作。我只是想听听答案是什么。即使你的枚举继续有效,至少可以说依赖这种行为听起来很危险。如果您认为其他人正在使用某个变量,那么您的代码不应该将该变量设置为null。如果有您担心的情况,您应该具体处理它们。我同意这不是您希望在代码中执行的操作。我只是想听听答案是什么。