OnClicked事件中Singleton的MedicineList属性无法同步更新问题咨询
问题核心原因
你遇到的赋值不生效完全不是线程相关问题,根源是Lists类的MedicineList属性实现逻辑错误:
该属性的
get访问器每次被调用时,都会执行return new List<MedicineInfo>(){...},也就是每次访问都会返回一个全新的、独立的列表实例。
你在Dingle_Clicked方法里执行赋值的流程实际是这样的:
- 触发一次
MedicineList的get调用,拿到一个临时的全新列表 - 从这个临时列表里取出
medIndex对应的MedicineInfo对象,遍历它的Prices集合修改MedicincePrice值 - 整个方法执行完后,这个临时列表没有被任何地方引用,会直接被GC回收,所有修改都随着临时实例一起被丢弃
- 等你后续写
ScraperBrowser.Navigate(Lists.Singleton.MedicineList[medIndex].GoodRxUrlString)时,会再次触发MedicineList的get调用,重新new一个全新的列表,自然完全读取不到之前的修改。
修复方案
只需要将MedicineList的实现从「每次访问都新建实例」改成「单例初始化时构造一次,后续永久复用同一个实例」即可:
将Lists类的代码替换为如下实现:
public class Lists { private static Lists _singleton; // 私有字段存储仅初始化一次的MedicineList实例 private readonly List<MedicineInfo> _medicineList; public static Lists Singleton { get { if (_singleton == null) _singleton = new Lists(); return _singleton; } } // 私有构造函数,仅在单例第一次初始化时执行一次 private Lists() { _medicineList = new List<MedicineInfo>() { new MedicineInfo() { Name = "ZOLPIDEM TAB 10MG", Doses = "30 tablets" }, new MedicineInfo() { Name = "PANTOPRAZOLE TAB 40MG", Doses = "30 tablets" } }; } // get直接返回已初始化的私有字段,不再新建实例 public List<MedicineInfo> MedicineList { get => _medicineList; } }
修改完成后,无论多少次访问Lists.Singleton.MedicineList,拿到的都是同一个列表实例,你对列表内StorePriceData对象的MedicinePrice属性的修改会被永久存储,后续读取时可以正常拿到更新后的值。
后续优化提示
- 当前的单例实现是非线程安全的,如果存在多线程首次访问
Singleton属性的场景,可能会构造出多个单例实例,后续可以改用Lazy<T>实现或者加锁优化,该问题不影响当前赋值不生效的核心问题 MedicineInfo类的构造函数逻辑无需修改,修复后它会在单例初始化时被构造一次,内部的Prices列表也会被固定复用,正常支持属性更新。
内容的提问来源于stack exchange,提问作者Carl Forgey
相关产品推荐
相关产品推荐

