C# 实现Dictionary数据对象的深度拷贝
最近由于在做聊天调度服务,场景是这样的,集群聊天服务器,每台服务通过socket按照一定的频率发送UDP数据包给调度服务器,调度服务器接收各台聊天服务器发来的数据包,然后进行相应的数据分析,最后裁定目前最空闲的聊天服务器,以供聊天用户实时快速连接最优服务器,我考虑使用Dictionary数据结构来缓存收集到的服务器汇总数据,开发的过程中遇到几个比较棘手的问题:
1、收集的数据是通过多线程进行的,这样造成Dictionary线程安全的问题。
针对Dictionary线程安全的问题,我通过继承IDictionary,重新构造线程安全Dictionary对象,这里其实没有什么复杂的,只是在Dictionary内部元素增加,删除、删除的时候加上锁。
2、这样线程安全的问题解决了,但是另一个问题出现了,我要对Dictionary中的数据进行相关分析操作,我想到实时拷贝一份Dictionary数据,拿过来进行相关分析,这样对Dictionary深度拷贝的问题出现了,经过查证,通过新建另外一个Dictionary对象,然后遍历原始Dictionay结构和数据进行赋值工作,通过.net反射机制实现了拷贝操作,但是性能很差,另外一种解决方案是通过序列化和反序列化的方式来完成数据对象的深度拷贝工作,这种方式快速高效,所以采用了这种方式,这里只贴出第二种方式:
public class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICloneable
{
public object Clone()
{
BinaryFormatter Formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
MemoryStream stream = new MemoryStream();
Formatter.Serialize(stream, this);
stream.Position = 0;
object clonedObj = Formatter.Deserialize(stream);
stream.Close();
return clonedObj;
}
}
实现深度拷贝工作,只需这个类继承ICloneable接口,通过BinaryFormatter序列化器,首先先将对象实例序列化写入内存流中,然后反序列化流,返回反序列化对象即可,
这种方式简单高效,是一种很好的解决方案,有时候换一种思路,把思考放宽,会有意想不到的效果。