我正在运行服务器,我希望有一个用户词典,并为每个用户提供一个特定的号码。
Dictionary<int,ServerSideUser> users = new Dictionary<int,ServerSideUser>();
密钥代表服务器上的用户,因此当人们向该用户发送消息时,他们会将消息发送给该号码。我不妨使用用户的IP号码,但这不是一个好主意。
我需要为每个用户分配这样一个号码,我真的不知道该怎么做。有人建议像
Enumerable.Range(int.MinValue, int.MaxValue)
.Except(users.Select(x => x.Key)).First();
但我真的不认为这是最佳方式。 另外,我在其他地方的List(或LinkedList)也有同样的问题。
有什么想法吗?
答案 0 :(得分:9)
如果“数字”的大小无关紧要,请选择Guid,它将始终是唯一且不可猜测的。
答案 1 :(得分:3)
如果你想要一个使用任意有序整数键的字典,你也可以使用List<ServerSideUser>
,其中列表索引用作键。
是否有特定原因需要使用Dictionary
?
使用List<>
或类似的数据结构肯定有局限性。由于并发问题,您根本不想从列表中删除用户,除非在循环服务器时。否则,您可能会遇到这样的情况:用户255向用户1024发送消息,用户1024断开连接并被新用户1024替换。新用户1024然后接收针对旧用户1024的消息。
如果您希望能够管理用户列表的内存占用,那么许多其他方法都可以使用;如果您想使用ints
而不是Guids
,Will's answer会特别好。
答案 2 :(得分:1)
为什么不跟踪当前的最大数量,并在每次添加新用户时将该数字增加一个?
答案 3 :(得分:1)
另一个选项:使用工厂生成ServerSideUser实例,为每个用户分配一个新的唯一ID。
在此示例中,工厂本身就是类。您无法实例化该类,您必须通过调用该类型上的静态Create方法来获取新实例。它递增ID生成器并使用此新id创建新实例。有许多方法以线程安全的方式执行此操作,我在这里以一种基本的1.1兼容方式(可能实际编译的c#伪代码)执行此操作:
public class ServerSideUser
{
// user Id
public Id {get;private set;}
// private constructor
private ServerSideUser(){}
private ServerSideUser(int id) { Id = id; }
// lock object for generating an id
private static object _idgenLock = new Object();
private static int _currentId = 0; // or whatever
// retrieves the next id; thread safe
private static int CurrentId
{
get{ lock(_idgenLock){ _currentId += 1; return _currentId; } }
}
public static ServerSideUser Create()
{
return new ServerSideUser(CurrentId);
}
}
答案 4 :(得分:1)
我建议你的方法和增量的结合。
由于您的数据在内存中,因此使用int类型的标识符就足够了。 为下一个用户和免费标识符的链接列表创建一个变量。
添加新用户后,请使用列表中的ID。如果列表为空 - 使用变量并递增它。
删除用户后,将其标识符添加到词典中。
P.S。考虑使用数据库。
答案 5 :(得分:1)
首先,我还首先考虑GUID建议。其次,我假设你以某种方式在服务器上持久保存用户信息,并且这可能是一个数据库。如果是这种情况,为什么不让数据库通过主键为每个用户选择一个唯一的ID?也许这不是你在这里尝试做的最好的选择,但这是数据库多年来一直处理的问题,那么,为什么要重新发明呢?
答案 6 :(得分:0)
我认为这取决于您如何定义客户的“唯一性”。
例如,如果您在同一台计算机上有两个不同的客户端,您认为它们是两个客户端还是一个?
我建议您使用long值表示连接建立的时间,如“hhmmss”,甚至可以包含毫秒
答案 7 :(得分:0)
为什么不从1开始向上计数?
lock(dict) {
int newId = dict.Count + 1;
dict[newId] = new User();
}
如果您真的担心一半的世界人口出现在您的服务器上,请尝试使用long:s而不是...... :-D
答案 8 :(得分:0)
也许有点野蛮,但DateTime.Now.Ticks可能适合你吗?作为额外的奖励,您知道用户何时被添加到您的词典中。
来自关于Ticks的MSDN文档...
单个刻度表示一百纳秒或一百万分之一 第二。一毫秒内有10,000个滴答。
此属性的值表示100纳秒间隔的数量 已经过了自0001年1月1日午夜12:00:00起 表示DateTime .. ::。MinValue。