我正在使用异步套接字在 c# 中开发游戏 emu。目前,该程序使用 List 来存储客户端。
如果客户加入一个房间,则会创建一个本地列表来存储来自该特定房间的所有用户(我正在使用 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 的客户端可变布尔值更改为 false(这意味着在执行套接字操作之前检查用户是否仍然连接像 BeginSend 等)。如果一个客户端从房间 X 断开连接,而其他客户端加入房间 X 怎么办?它肯定仍会在本地列表中,但 ConnectionFired 布尔值会改变它的值吗?我猜不是。它只影响主/原始列表。
我担心的是,如果发生这种情况,那么服务器可以尝试将数据发送到一个关闭的套接字(因为检查这个的布尔值 ConnectionFire 在需要时不会改变它的值)。
为了避免这种事情,我应该避免对列表进行克隆,并直接在主列表上使用for吗?(我最初做这个 locallist 的事情是为了避免集合被修改异常)。