C
C#•10mo ago
CrosRoad95

Thread safe moving value between two objects

I have problem. Consider following class:
public class Foo {
public int Amount { get; set; }
public int MaxAmount { get; set; }
}

var foo1 = new Foo{ Amount = 75, MaxAmount = 100 };
var foo2 = new Foo{ Amount = 75, MaxAmount = 100 };
public class Foo {
public int Amount { get; set; }
public int MaxAmount { get; set; }
}

var foo1 = new Foo{ Amount = 75, MaxAmount = 100 };
var foo2 = new Foo{ Amount = 75, MaxAmount = 100 };
what i want to do is to thread safe move amount from one "Foo" object, to another that it won't overflow above "MaxAmount".
foo1.Transfer(foo2, 25); // Ok, foo2 now is full, foo1 have amount 50, foo2 amount 100
foo1.Transfer(foo2, 25); // Throw overflow exception, because 100 + 25 > 125
foo1.Transfer(foo2, 100); // Throw other exception, because now foo1 have Amount = 50
foo1.Transfer(foo2, 25); // Ok, foo2 now is full, foo1 have amount 50, foo2 amount 100
foo1.Transfer(foo2, 25); // Throw overflow exception, because 100 + 25 > 125
foo1.Transfer(foo2, 100); // Throw other exception, because now foo1 have Amount = 50
A bif more context: It is for game for items stacking purpose, it is used server side so two clients at once may attempt to move items. Please focus on thread safety aspect
11 Replies
canton7
canton7•10mo ago
... locks? It's unclear what your problem is. Your post doesn't actually contain a question.
CrosRoad95
CrosRoad95OP•10mo ago
I know that i can use locks, but how? 😂 do you know nice pattern?
canton7
canton7•10mo ago
lock (lockObject)
{
// Logic to transfer amounts
}
lock (lockObject)
{
// Logic to transfer amounts
}
CrosRoad95
CrosRoad95OP•10mo ago
Right now i endup with lock spaghetti, but i know someone know nice solution Had idea to do inventory level lock for items changing purpose But, items can be stacked across inventories so i endup with same issue just level highier
canton7
canton7•10mo ago
I think you've over-simplified your question? Your actual problem isn't really related to your post
Buddy
Buddy•10mo ago
Either manual locks or the use of Interlocked class
CrosRoad95
CrosRoad95OP•10mo ago
Had idea to introduce some helper method like public IDisposable EnterWrite() that i can lock object from outside
{
using var lk1 = foo1.EnterWrite();
using var lk2 = foo2.EnterWrite();
// Change amount
}
{
using var lk1 = foo1.EnterWrite();
using var lk2 = foo2.EnterWrite();
// Change amount
}
What do you think about pattern like this ^
canton7
canton7•10mo ago
Prone to deadlocks, if someone tries to acquire those same locks in the opposite order Why can't you have one lock for everything? You're never going to be holding it for more than a couple of instructions, so it'll probably never be contended
Omnissiah
Omnissiah•10mo ago
another pattern could be a queue of actions of players (so that they are serialized) but it depends on what game is this (like 3d fps, 2d action, textual...)
CrosRoad95
CrosRoad95OP•10mo ago
Maybe 🤔
br4kejet
br4kejet•10mo ago
Something like that seems like it should only ever really be done on a single or "safe" thread, not just any random thread So if you can, you could invoke your game thread's dispatcher or scheduler (or whatever the equivalent is for what you're using) and use it to invoke the modification on that thread But if you're saying a client wants to modify that value, then i'd probably just implement a data packet system where client sends something like AddFooPacket And process those packets on the main/server/game thread If it's a 3d game for like an inventory/chest management system then it might not be that straight forward, it could be something like PlayerClickGuiPacket, then maybe you invoke an interface method e.g. IContainer.OnPlayerClick(double x, double y, Foo itemInHand) or something along those lines (and you'd need some way of serialising/deserialising Foo ofc) I dunno what that concept is called but the idea is the client and server sync their data via packets (by updating server or being notified of server changes). Not sure if this is what you're going for
Want results from more Discord servers?
Add your server