2011-06-28 57 views
0

我创建具有2类C#螺纹锁定问题

溶液

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

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

classes[0].Id = i++; 

方法2:返回静态列表

但我不断收到异常名单无法修改。

我想确保一次只有一个方法锁定类对象。我能做些什么来实现它?锁(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++; 
} 

} 

请注意,我想修改类的列表对象作为更新的对象正在由另一个方法返回。

+2

什么是异常消息的确切措辞?你在哪一行代码中得到它?如果你发布了更多的代码,这可能会有帮助,所以我们可以看到发生了什么。 –

+0

也许你可以尝试使用不同于List <>的类,可能是[System.Collections.Concurrent](http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx)如果您使用的是4.0,或者至少实现了对列表的某些管理访问 –

+0

如果迭代列表时列表被修改,则会引发该类型的异常。这可以在foreach块内的同一个线程上或单独的线程中。 – eulerfx

回答

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(你的消息泵)将直接或通过对实例的接口访问答:如果你真的需要静态,那么使_list和_lock是静态的(但我不喜欢那样)。

前面已经提出,需要有例外

+0

_list = new List 每次创建一个新的类对象。我只想在A班的一生中创建一个对象。 A类实际上是一个WCF服务,我的客户... B类正在调用 – InfoLearner

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

}