C# 修改锁定块中的锁定对象

C# 修改锁定块中的锁定对象,c#,synchronization,thread-safety,C#,Synchronization,Thread Safety,我在OLTP应用程序中遇到线程争用。在查看相关代码时,我发现了以下内容: lock (_pendingTransactions) { transaction.EndPointRequest.Request.Key = (string)MessageComparer.GenerateKey(transaction.EndPointRequest.Request); if (!_pendingTransactions.

我在OLTP应用程序中遇到线程争用。在查看相关代码时,我发现了以下内容:

        lock (_pendingTransactions)
        {
            transaction.EndPointRequest.Request.Key = (string)MessageComparer.GenerateKey(transaction.EndPointRequest.Request);

            if (!_pendingTransactions.ContainsKey(transaction.EndPointRequest.Request.Key))
            {
                _pendingTransactions.Add(transaction.EndPointRequest.Request.Key, transaction);

                return true;
            }
            else
            {
                return false;
            }
        }

正如您在代码段中看到的,在“lock”块中修改的对象上有一个锁。这有什么不好吗?任何人在做这样的事情时都会遇到问题?

一般来说,一个人会锁定一个对象,特别是因为他要修改(或读取)它,所以这本身没有什么问题。

通常不鼓励以这种方式使用锁定,建议使用专用的锁定字段(类成员变量). 专用锁定字段的类型为
Object
,通常如下所示:

private object _pendingTransactionLock = new object();
如果对象本身具有某种线程意识,则此锁变量可能属于
\u pendingTransaction
的实现类。否则,它可能与
_pendingTransaction
一起属于字段的声明类

你没有说什么类型的
_pendingTransaction
。如果这是一个提供
SyncRoot
属性的内置集合类,那么锁定它可能是一个不错的选择


参见Jon Skeet的选择要锁定的内容。

可能可以在锁块之外生成密钥,以缩短锁的持续时间。除此之外,这是一个几乎是保护列表/集合/数组的锁的典型示例:获取锁,检查密钥是否存在,添加密钥(如果尚未存在),释放锁