最近由於在做聊天調度服務,場景是這樣的,集群聊天服務器,每台服務通過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序列化器,首先先將對象實例序列化寫入內存流中,然后反序列化流,返回反序列化對象即可,
這種方式簡單高效,是一種很好的解決方案,有時候換一種思路,把思考放寬,會有意想不到的效果。