I have got the following code:
public void Update(Foo foo)
{
lock(_locker)
{
UpdateFirstPart(foo.First);
UpdateSecondPart(foo.Second);
UpdateThirdPart(foo.Third);
}
}
public class Foo
{
public int Id;
public Some1 First;
public Some2 Second;
public Some3 Third;
}
Method Update
can be performed in two or more threads and I use lock
to prevent cuncurency problems with foo
. But I would like to lock only those Foo
that have similar Id
. For instance if one thread executes method Update
with Foo.Id = 1 and another thread executes Update
with Foo.Id = 2 then lock
is not needed and if two threads execute Update with two instances Foo
with the same Id
, lock
is needed. Is it possible to create a such lock?
Object Lock can help prevent objects from being deleted or overwritten for a fixed amount of time or indefinitely. You can use Object Lock to help meet regulatory requirements that require WORM storage, or to simply add another layer of protection against object changes and deletion.
Lock an object in placeSelect the Inspector from the toolbar. In the Inspector, select the Lock tab. Select an object (or objects) on the canvas that you would like to lock. Choose Lock.
You could use ConcurrentDictionary<TKey, TValue>
for storing your locks.
private static readonly ConcurrentDictionary<int, object> ThreadLockDict =
new ConcurrentDictionary<int, object>();
And use it in Update method:
public static void Update(Foo foo)
{
// add a new locker object for each foo if it's not already in dictionary
ThreadLockDict.TryAdd(foo.Id, new object());
lock (ThreadLockDict[foo.Id])
{
// some code
}
}
You could use this class to get a lock object for every Id:
public class MultiLockObjects<TKey>
{
private readonly ConcurrentDictionary<TKey, Object> _multiLocker = new ConcurrentDictionary<TKey, Object>();
public Object this[TKey key]
{
get
{
Object lockObj = _multiLocker.GetOrAdd(key, tKey => new Object());
return lockObj;
}
}
}
Then hold an instance of it in your class:
private MultiLockObjects<int> _idLocks = new MultiLockObjects<int>();
Usage is simple:
public void Update(Foo foo)
{
Object idLockObject = _idLocks[foo.Id];
lock (idLockObject)
{
UpdateFirstPart(foo.First);
UpdateSecondPart(foo.Second);
UpdateThirdPart(foo.Third);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With