c# - 为什么锁定我们要更改的对象是一种不好的做法?

标签 c# multithreading locking

为什么在下面的代码中使用锁是一种不好的做法,我假设这是一种基于 this SO question here 中答案的不好的做法。

private void DoSomethingUseLess()
{
    List<IProduct> otherProductList = new List<IProduct>();
    Parallel.ForEach(myOriginalProductList, product =>
        {
           //Some code here removed for brevity
           //Some more code here :)
            lock (otherProductList)
            {
                otherProductList.Add((IProduct)product.Clone());
            }
        });
}

关于 there 的答案提到这是不好的做法,但他们没有说明原因

注意:请忽略代码的用处,这只是为了示例目的,我知道它根本没有用

最佳答案

来自 C# 语言引用 here :

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 because 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 (otherProductList) 
{
    otherProductList = new List<IProduct>(); 
}

...那么你的锁就一文不值了。由于这些原因,建议使用专用的 object 变量进行锁定。

请注意,这并不意味着如果您使用您发布的代码,您的应用程序将中断。 “最佳实践”通常被定义为提供在技术上更具弹性的易于重复的模式。也就是说,如果您遵循最佳实践并拥有一个专用的“锁对象”,您就不太可能永远编写损坏的基于lock 的代码;如果您不遵循最佳实践,那么您可能会被一个很容易避免的问题困扰,可能是百分之一。

此外(更一般而言),使用最佳实践编写的代码通常更容易修改,因为您可以减少对意外副作用的警惕。

关于c# - 为什么锁定我们要更改的对象是一种不好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11775205/

相关文章:

c# - 当 treenodeclick 打开表单时,表单落后

c# - 值类型和原始类型有什么区别?

c++ - 加速 Monte Carlo Pi

java - 您的 Java 低延迟应用程序的开发 list 是什么?

mysql - 没有明显锁的 ActiveRecord "Mysql::Error: Lock wait timeout exceeded"

c++ - 无需复制即可线程安全读取类成员 vector

locking - 在 Hazelcast 中,是否可以使用不关心执行锁定/解锁操作的本地线程的集群锁?

c# - Request.IsAuthenticated 如何工作?

java - 如何为运行正则表达式的 Java 函数设置时间限制

c# - 让循环等待 Action 完成