我已经清理并缩短了多用户游戏的代码片段,以显示我想要完成的操作。所以在这里,它是:正确处理跨线程共享类的锁定方式
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 { get { return opened; } }
}
我想知道的是: 如何防止某些用户(从另一个线程执行代码)来打开当前正在由其他一些用户拿起一个盒子。 我已经想到了一些方法,但我认为这里的人经常想出聪明的想法,这可以让我避免一些愚蠢的设计问题。
编辑:正如在回答提出,要使用锁关键字在打开的方法:这是不是我想要什么,我会尝试用解释是允许什么,什么不是:
网络我们得到的请求以某种方式异步并且如果发布得很快就会出错。
- (1)用户1次发出指令PICKUP BOX
- (2)用户1次发出指令OPEN BOX
- (3)用户1所发出命令关闭BOX
- (4)用户2次发出指令OPEN BOX
- (5)用户2次发出指令LOOK BOX
- (6)用户1次发出指令打开框中
我们得到这个顺序:
2,3,1,5,4,6
2 - allow
3 - allow
1 - allow [remains in execution and has not set the owner]
5(comes in between 1) - allow
4(comes in between 1) - disallow (not because already open but because 1 is in execution)
6(comes in between 1) - allow since it is from user 1, and he is currently picking it up
谢谢!
我发布将满足新的条件解决方案 - TryOpen( )将在(3)执行时返回false。如果需要,您可以将相同的方法应用于其他方法以满足进一步的条件。 – 2011-04-12 04:07:52
在tcp中,据我所知,消息的顺序是保证的,所以可能发生的最坏情况是1,3,4,2 - 这是你必须在你的代码中处理的,意思是记住谁'拥有'哪个对象 – 2011-04-12 04:09:26
到目前为止正如我所看到的,如果有时候命令不同步,如果它们发出的速度非常快,似乎每个命令都有一个连接,而不是一个连接,但是不是我的代码的一部分,我不是专家......:/ – 2011-04-12 04:16:06