I’m having thread contention in an OLTP app. While reviewing the code involved, I found the following:
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;
}
}
As you can see in the snippet, there is a lock on an object that is modified within the ‘lock’ block. Is there anything bad with that? Anyone had problems doing something like this?
Using locking in this way is often discouraged, with the recommendation being to use a dedicated lock field (class member variable). A dedicated lock field is of type
Objectand usually looks like this:If the object itself has some threading awareness, this lock variable might belong in
_pendingTransaction‘s implementation class. Otherwise, it might belong alongside_pendingTransactionin the field’s declaring class.You don’t say what type
_pendingTransactionis. If this is a built-in collection class that provides aSyncRootproperty, that might be a good choice to lock on.See Jon Skeet’s Choosing What to Lock On.