0

In C#, it's well documented that locking on public objects is a bad idea, because we don't know who else might lock on that object, potentially causing problems like deadlocks. So we create private objects to serve as these locks. If we have a custom collection, for example, that needs to be able to modify items in a thread-safe way, we might want to be able to associate a unique private object with each item for locking.

As an example, instead of doing this:

lock (publicObject[i])
{
    // modify publicObject[i]-related data
}

We should be doing something like this:

var lockObject = GetLockObject(i); // GetLockObject is private
lock (lockObject)
{
    // modify publicObject[i]-related data
}

The former is much simpler when an object might be added, modified, or removed at any time, as creating or removing the associated object for locking requires some care. However, how to do that isn't a terribly hard problem, and it's not what I'm asking how to do here.

Instead of having a private object for locking for each item in the collection, it'd be much simpler to be able to have one private object that serves as "context" for the lock. Any other lock on the same public object that does not also use the same "context" will not block or be blocked by this code. If I could do something like this, it'd solve the problem of not knowing whether this object is used as a lock elsewhere, without me having to create a unique lock object for each thing I want to lock on. Something like this:

lock (_lockObject, publicObject[i])
{
    // modify publicObject[i]-related data
}

We don't have to care if anything else outside this class is locking on publicObject[i], because they won't block or be blocked by this snippet. But inside this class, wherever I want to lock on publicObject, I lock on the pair (_lockObject, publicObject[i]) instead.

But that obviously isn't a feature of C#, and locking on Tuples doesn't work, because they're value types. Is there a simple way to do this in C# at the moment? And by "simple" I mean simpler than maintaining a collection of corresponding objects for locking.

Thanks!

Jibb Smart
  • 295
  • 3
  • 15
  • 2
    No you cant do this, you will have to roll your own solution. Its hard to go forward from here, because its hard to see the problem your trying to solve. As it stands you just want a sometimes-lock, which would assume you have a great understanding of what needs to be thread safe. usually you just lock the shared resource, and if you have 2 shared resources you lock them both. There are several ways you can achieve more fine grain control, but it really depends on the problem – TheGeneral Mar 05 '20 at 03:59
  • *In C#, it's well documented that [stackoverflow link]*. I don't think that [Stack Overflow](https://stackoverflow.com) serves as documentation for the .NET Framework or the C# language, or anything really. This is just a questions-answers site! – Theodor Zoulias Mar 05 '20 at 11:52
  • Your second code sample, where you use a **private** lock object to obtain exclusive access to a **public** resource, looks scary to me. The whole point of locking is to prevent concurrent access to the same resource from multiple threads. If anyone is using its own private lock to gain access to the public resource, then the objective of exclusivity will not be achieved! – Theodor Zoulias Mar 05 '20 at 12:02
  • @TheodorZoulias The linked question links to the actual documentation and asks "why". The answers help explain why. – Jibb Smart Mar 05 '20 at 14:10
  • @TheodorZoulias Regarding that second code sample -- I'm not modifying the public resource, but modifying data I've associated with a public resource. For example (in the real life situation that prompted this question), the public resource is a key in a kind of dictionary, and the key would make a useful lock when adding or removing entries, or modifying values. That aside, the purpose of the private lock is to control the scope of your own blocking, not to prevent that anything else anywhere modify the object in question. Lock's purpose isn't to guarantee exclusive access to the locked obj. – Jibb Smart Mar 05 '20 at 14:20
  • *the purpose of the private lock is to control the scope of your own blocking* <--- I have no idea what this means. Could you provide a minimal example with the essential ingredients of your real life situation? – Theodor Zoulias Mar 05 '20 at 15:00

0 Answers0