我正在使用异步套接字在C#中开发游戏e。当前,该程序使用列表来存储客户端。
如果客户端加入 session 室,则会创建一个本地列表,该列表存储该特定 session 室中的所有用户(我正在使用FindAll(x => x.room == this.room))。该列表是必需的,因为当客户更改房间时,服务器必须发送特定的数据包以宣布该客户加入的房间中的所有其他玩家。
像这样的东西:
var localist = Clients.FindAll(x=> x.room == this.room);
foreach(stateObj client_in_room in locallist)
{
client_in_room.sendPacket(...); //what if the client_in_room disconnected in the meanwhile?
}
当客户端断开连接时,它将(stateObj)从原始客户端列表中移除(并且客户端套接字关闭),并且一个名为ConnectionFired的客户端 volatile bool 值更改为false(用于在执行套接字操作之前检查用户是否仍处于连接状态)例如BeginSend等)。如果某个客户从X session 室断开连接而其他一些客户加入X session 室怎么办?当然,它仍然会在本地列表中,但是ConnectionFired bool会更改其值吗?我猜不是。它仅影响主/原始列表。
我担心的是,如果发生这种情况,那么服务器可以尝试将数据发送到封闭的套接字(因为检查此问题的 bool 值ConnectionFire在需要时不会更改其值)。
为避免这种情况,我应该避免对列表进行克隆,而直接在主列表中将用作吗? (我最初做了这个locallist的事情是为了避免集合被修改的异常)。
最佳答案
你似乎在这里问两个问题
在信息有限的情况下回答您的问题
http://msdn.microsoft.com/en-us/library/dd997305.aspx
关于您对“本地”列表的评论,简单的答案是不制作本地副本,除非您要冒拥有过时数据的风险。使用线程安全列表,并直接对其进行枚举。如果使用LINQ表达式,则可以进行复杂的查询,而无需制作集合的任何副本。
关于c# - C#多线程服务器-通用客户端集合可能是一个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18723229/