You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否误解C#类的实例隔离特性?多实例数据混乱问题求助

问题:多实例数据互相干扰,学生拿到错误的患者报告结果

我设计了一个Attainment类,用来整合各类数据、执行逻辑测试并生成输出,应用场景是学生完成患者报告后计算所得学分。原本以为类实例化后,内部所有数据与逻辑都是相互隔离的,多名学生同时完成报告、各自触发类实例化并调用学分重建方法时,不同实例的数据不会互相干扰,但实际出现了学生获取到不属于自己的患者报告结果的问题。

相关代码如下:

public class Attainment
{
    public int StudentID { get; set; }
    public int PatientID { get; set; }

    static DataTable dtAttainmentList;
    static DataTable dtClassroomData;


    public Attainment()
    {
        dtAttainmentList = new DataTable();
        dtAttainmentList.Columns.Add("boxUID", typeof(string));
        dtAttainmentList.Columns.Add("type", typeof(int));
        dtAttainmentList.Columns.Add("patientID", typeof(int));
    }

    public static void Rebuild(int thisStudentID, int thisPatientID)
    {
        Attainment test = new Attainment();
        test.StudentID = thisStudentID;
        test.PatientID = thisPatientID;
        test.GenerateAttainments(); 
    }

    public void GenerateAttainments()
    {
        // 为简洁起见省略了其他方法,核心逻辑如下:
    
        dtClassroomData = GetClassroomData();
    
        // 从数据库删除旧记录
        
        // 执行新逻辑

        // 向数据库插入新记录
    }

    
    DataTable GetClassroomData()
    {
        // 创建新数据表
        // 从数据库填充数据
        // 返回数据表
    }

}
问题根源与解决方法

问题根源

代码里的dtAttainmentList和dtClassroomData是静态(static)成员,静态成员属于类本身,而非类的实例。所有Attainment实例都会共享这两个静态DataTable:

  • 当多个学生同时触发Rebuild时,新实例初始化会覆盖之前的dtAttainmentList
  • 多个实例在GenerateAttainments中同时修改dtClassroomData,导致数据互相覆盖,最终写入数据库的是混乱的混合数据,自然出现学生拿到错误结果的情况

解决方法

把静态的dtAttainmentList和dtClassroomData改成实例成员,让每个Attainment实例拥有独立的数据表:

public class Attainment
{
    public int StudentID { get; set; }
    public int PatientID { get; set; }

    // 去掉static修饰符,改为实例成员
    DataTable dtAttainmentList;
    DataTable dtClassroomData;


    public Attainment()
    {
        dtAttainmentList = new DataTable();
        dtAttainmentList.Columns.Add("boxUID", typeof(string));
        dtAttainmentList.Columns.Add("type", typeof(int));
        dtAttainmentList.Columns.Add("patientID", typeof(int));
    }

    public static void Rebuild(int thisStudentID, int thisPatientID)
    {
        Attainment test = new Attainment();
        test.StudentID = thisStudentID;
        test.PatientID = thisPatientID;
        test.GenerateAttainments(); 
    }

    public void GenerateAttainments()
    {
        dtClassroomData = GetClassroomData();
    
        // 从数据库删除旧记录
        
        // 执行新逻辑

        // 向数据库插入新记录
    }

    
    DataTable GetClassroomData()
    {
        // 创建新数据表
        // 从数据库填充数据
        // 返回数据表
    }

}

额外注意事项:

  • 如果Rebuild在多线程环境下调用,要确保数据库操作(删旧记录、插新记录)的线程安全,比如为每个学生的操作添加事务,避免不同学生的数据库操作互相干扰
  • 当前Rebuild静态方法的逻辑没问题,每个调用都会创建独立实例,修改静态成员为实例成员后就不会有数据共享的问题了

内容的提问来源于stack exchange,提问作者andym0908

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 11:40:23