c# - Correct way to handle locking of classes shared across threads -
i have cleaned , shortened snippet of code multiuser game show accomplish. here is:
public class subject { public list<iobject> objects = new list<iobject>(); } public interface iopenable { void open(subject by, params string[] p); void close(subject by, params string[] p); bool isopen { get; } } public interface iobject { void pickup(subject by, params string[] p); void drop(subject by, params string[] p); } public class box : iobject, iopenable { bool opened = false; subject owner = null; public void pickup(subject subject, params string[] p) { subject.objects.add(this); this.owner = subject; } public void drop(subject subject, params string[] p) { subject.objects.remove(this); this.owner = null; } public void open(subject by, params string[] p) { this.opened = true; } public void close(subject by, params string[] p) { this.opened = false; } public bool isopen { { return opened; } } } what know is: how prevent user (executing code thread) open box being picked other user. i've thought of ways think people here come clever ideas, make me avoid stupid design issue.
edit: suggested in answers, use lock keyword in open method: not want, i'll try explain allowed , not:
the network requests input somehow async , out of order if issued fast.
- (1) user 1 issues command pickup box
- (2) user 1 issues command open box
- (3) user 1 issues command close box
- (4) user 2 issues command open box
- (5) user 2 issues command box
- (6) user 1 issues command open box
we order:
2,3,1,5,4,6
2 - allow 3 - allow 1 - allow [remains in execution , has not set owner] 5(comes in between 1) - allow 4(comes in between 1) - disallow (not because open because 1 in execution) 6(comes in between 1) - allow since user 1, , picking thanks!
you can use lock statement prevent 2 threads accessing open , close. prevent race condition on checking if box opened, can change open() tryopen(), , return false if box open. there ways don't have return boolean, simplest.
if 1 thread reaches lock statement while thread inside lock statement, second thread wait until first thread exits lock statement before continuing.
private object locker=new object(); public bool tryopen(subject by, params string[] p) { lock(locker) { if(this.opened) return false; this.opened = true; return true; } } public void close(subject by, params string[] p) { lock(locker) { this.opened = false; } }
Comments
Post a Comment