C#线程锁定问题

本文关键字:问题 锁定 线程 | 更新日期: 2023-09-27 18:00:50

我正在创建一个有两个类的解决方案

类A有一个公共静态List对象,即public static List<MyClass> classes = new List<MyClass>();类B具有使用System.Threading.Timer运行的方法,以及按时间间隔调用类A的方法

A类有两种方法方法1:更新静态列表-查找项目并增加其属性,例如

classes[0].Id = i++;

方法2:返回静态列表

但我一直得到一个例外,列表不能修改。

我想确保一次只有一个方法锁定classes对象。我能做些什么来实现它?锁定(this(或锁定(classes(不起作用。

例外情况是

list cannot be modifed when it is being enumerated.

它指向classes[0].Id递增的线

代码为:

for (int i = 0; i< classes.Count;i++)
{
if (classes[i].Name == this.NameToFind)
{
classes[i].Id = n++;
}
}

请注意,我想修改classes列表对象,因为其他方法正在返回更新的对象

C#线程锁定问题

听起来A类应该更少地暴露其内部。你没有说太多关于设计,但这(或类似的工作(

class A{
  List<MyClass> _list = new List<MyClass>();
  object _lock = new object();
  public void Increment(int index){
     lock(_lock) {/*find item and increment */}
  } 
}

理想情况下,没有静态状态,B(您的消息泵(可以直接或通过接口访问A的实例。如果真的需要静态,则将_list和_lock设置为静态(但我不喜欢这样(。

如前所述,需要更多关于异常的信息

根据对答案的一些评论,A类是Wcf服务,B类是消费服务。这些细节可能很重要,因为返回的内容都要经过序列化。

从你对这个例外的描述来看,我认为我们遗漏了细节。使用枚举器的东西不应该出现错误。

至于锁定,听起来你需要一个私有的静态对象来锁定(因为我猜你想在实例化的wcf调用之间同步该静态列表上的操作(,但这取决于你如何设置wcf并发模式。可能有比下面的例子更有效的方法来处理同步,但据我所知,这是我所能做的。确保任何触及私有列表的东西都在静态锁内这样做。你可能应该调查一下读者和作家的瘦锁http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

(手写(

class A
{
     private static readonly object listLock = new object();
     private static List<MyClass> classes = new List<MyClass>();
     public void Method1()
     {
          lock(listLock)
          {
               //update here
          }
     }
     public List<MyClass> Method2()
     {
          lock(listLock)
          {
               return classes;
          }
     }
}