C#螺纹锁定问题

时间:2011-06-28 23:21:00

标签: c#

我正在创建一个包含2个类的解决方案

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

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

classes[0].Id = i++;

方法2:返回静态列表

但是我一直不知道列表无法修改。

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

例外是

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++;
}

}

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

2 个答案:

答案 0 :(得分:0)

听起来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实例的接口访问。如果真的需要静态,那么make _list和_lock static(但我不喜欢那样。)

正如已经提到的那样,需要有关于异常的更多信息

答案 1 :(得分:0)

根据答案的一些评论,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;
          }
     }

}