Skip to main content
 首页 » 编程设计

c#之如何在 IList 上使用锁

2024年01月29日34EasonJim

我有一个实现了 IList 接口(interface)的静态集合。该集合在整个应用程序中使用,包括添加/删除项目。

由于多线程问题,我想知道我能做些什么来确保列表一次修改一个,例如当一个线程尝试添加一个项目时,另一个线程此时不应该删除项目。

我想知道 lock(this) 和 lock(privateObject) 有什么区别?哪个对我来说更好?

谢谢。

请您参考如下方法:

lock(this) 将锁定整个实例,而 lock(privateObject) 将只锁定特定的实例变量。第二个是更好的选择,因为锁定整个实例将阻止其他线程对该对象执行任何操作。

来自 MSDN :

In general, avoid locking on a public type, or instances beyond your code's control. The common constructs lock (this), lock (typeof (MyType)), and lock ("myLock") violate this guideline:

  • lock (this) is a problem if the instance can be accessed publicly.

  • lock (typeof (MyType)) is a problem if MyType is publicly accessible.

  • lock(“myLock”) is a problem since any other code in the process using the same string, will share the same lock.

Best practice is to define a private object to lock on, or a private static object variable to protect data common to all instances.

在这种特殊情况下,集合是静态的,这实际上意味着只有一个实例,但这仍然不会改变 lock(this) 和 lock(privateObject) 会表现出来。

即使在静态集合中使用 lock(this),您仍然会锁定整个实例。在这种情况下,一旦线程 A 获得了方法 Foo() 的锁,所有其他线程都必须等待以对集合执行任何操作。

使用 lock(privateObject) 意味着一旦线程 A 获得方法 Foo() 的锁,所有其他线程就可以执行任何其他 除了 Foo() 之外的操作无需等待。只有当另一个线程尝试执行方法 Foo() 时,它才必须等到线程 A 完成其 Foo() 操作并释放锁。