Dictionary<int, TS_EIT> Whole_EITOtherSchedule_dic = new Dictionary<int, TS_EIT>();
Dictionary<int, List<int>> Whole_EITOtherSchedule_ServiceIDtoEventIDs_dic = new Dictionary<int, List<int>>();
object EIT_Locker = new object(); private void TS_Analyze(FileStream fs, int Packetsize)
{
 for (int i = 0; i < fs.Length / Packetsize; i++)
 {
//**********
if (EIT.table_id >= 0x60 && EIT.table_id <= 0x6F)
                            {
                                lock (EIT_Locker)
                                {
                                    if (!Whole_EITOtherSchedule_dic.ContainsKey(EIT.service_id))
                                    {
                                        Whole_EITOtherSchedule_dic.Add(EIT.service_id, EIT);
                                        Whole_EITOtherSchedule_ServiceIDtoEventIDs_dic.Add(EIT.service_id, new List<int>());
                                        foreach (TS_EIT_Events EIT_Event in EIT.List_EIT_Events)
                                        {
                                            Whole_EITOtherSchedule_ServiceIDtoEventIDs_dic[EIT.service_id].Add(EIT_Event.event_id);
                                        }
                                    }
                                    else
                                    {
                                        foreach (TS_EIT_Events EIT_Event in EIT.List_EIT_Events)
                                        {
                                            if (Whole_EITOtherSchedule_ServiceIDtoEventIDs_dic[EIT.service_id].IndexOf(EIT_Event.event_id) < 0)
                                            {
                                                Whole_EITOtherSchedule_ServiceIDtoEventIDs_dic[EIT.service_id].Add(EIT_Event.event_id);
                                                Whole_EITOtherSchedule_dic[EIT.service_id].List_EIT_Events.Add(EIT_Event);
                                            }
                                        }
                                    }
                                }
}
}
  private void Tree_TS_Right_AfterExpand(object sender, DevComponents.AdvTree.AdvTreeNodeEventArgs e)
{
            string s = e.Node.TagString;
            if (e.Node.TagString == "EIT Other Schedule")
            {
                new System.Threading.Thread(
                    delegate()
                    {
                        lock (EIT_Locker)
                        {
                            foreach (TS_EIT EIT in Whole_EITOtherSchedule_dic.Values)
                            {
                                TSCommon.ComposeEIT(EIT, e.Node);//用信息组合树节点
                            }
                        }
                    }
                    ).Start();
            }
        }如上代码(没有贴出全部内容),为什么在事件里执行组合节点的方法还是提示集合已修改,我已经使用lock了,是用的不对吗?请大虾指教

解决方案 »

  1.   

    集合已修改的提示未必是因为多线程并发引起,也可能是你在TSCommon.ComposeEIT(EIT, e.Node)中修改了Whole_EITOtherSchedule_dic.Values的取值,
      

  2.   

    ComposeEIT只是用foreach遍历来添加节点,没有其他操作或功能
      

  3.   

    同意二楼,如果不是你方法里做了修改应该不会出错,不然你把TSCommon.ComposeEIT(EIT, e.Node);换成改成 string a = EIT.tostring();试下。
      

  4.   


    换成tostring之后,试了下展开事件点击的慢的话没事,快的话还是会报错
      

  5.   

    假如我把ComposeEIT()换成个试验的方法如e.Node.Nodes.Add(new Node("abc"))的话有时点展开不报错,有时开就会候报错为什么呢,快疯了
      

  6.   

    还有就是我把所有foreach的地方换成了for,也还是会报同样的错误为什么我现在看见这个集合已修改我就烦。。
      

  7.   

    你查下MSDN或者找一个C#的书看一下就知道:1、对集合类型的锁定,不应锁定对象,而是他的IsSyncal(记不太清楚是不是这么写的)属性。
    2、及时采取1中的方法,对集合类型的枚举操作是无法锁定的。
      

  8.   


    你说的是不是SyncRoot属性这是非泛型集合的属性,用来锁定用,泛型集合类似于我那么锁定应该是没问题的
      

  9.   

    static object EIT_Locker = new object();
      

  10.   

    用ConcurrentDictionary<TKey, TValue>类代替Dictionary<TKey, TValue>,即可解决问题。
      

  11.   

    在Dictionary上加锁是一定可以的,一定是你的代码中有什么地方对字典做了修改,不单指Whole_EITOtherSchedule_dic,还指Whole_EITOtherSchedule_dic中的某一个值TS_EIT做了修改。
    很可能你在某处对某一个TS_EIT中某一属性进行了修改,比如调用了一个方法进行计数之类的。不行你就复制吧后再使用吧。Dictionary<int, TS_EIT> aaa = new Dictionary<int, TS_EIT>(Whole_EITOtherSchedule_dic);
     foreach (string s in aaa.Values)
             { 
                //todo
             }
      

  12.   

    我用了try,catch都没用什么意思这是
      

  13.   

    是,说的具体点把,后来我加了日志记录进去,我在修改的地方设置了ADD日志记录,在绑定节点的地方设置了Bind日志记录,日志的结果就是,在BIND的时候根本就没有ADD过。直到报错程序崩溃,连try,catch都没用我就纳闷了
      

  14.   

    你只在这两个方法中使用了Whole_EITOtherSchedule_dic么。另请贴出
    TSCommon.ComposeEIT(EIT, e.Node)方法的代码
      

  15.   

    搞定了
    最终原因是因为我 new System.Threading.Thread的关系new 的线程不能修改主线程的也就是界面线程的东西so,我也不知道为什么报错是报集合已经修改这个错误不过问题解决了,谢谢大家,结贴~~~