本文转载自微信公众号《UP科技控》,作者conan5566。转载本文请联系UP技控公众号。背景最近还有一个需求,就是要在网站上埋点一些事件。说白了,就是记录用户的访问行为。那么如何保存这些数据,人家点击保存呢?显然不合适,必须分批保存才能提高效率。QuestionSnooping首先我想到的是Dictionary。相信大家对C#中的Dictionary类都不陌生。这是一个Collection(集合)类型,可以以Key/Value(键值对;该类最大的优点是查找元素的时间复杂度接近O(1)。在实际项目中,经常使用到本地缓存一些数据,提高整体效率Dictionary是非线程安全类型,可以先加入内存,批量保存进入数据库主要代码实现1.定义一个Dictionary.privatereadonlyDictionary>_storage=newDictionary>(StringComparer.OrdinalIgnoreCase);2.添加元素时,operate需要线程安全的处理,最简单办法是加锁。publicboolSaveObject(stringpath,Tvalue)whereT:class{if(String.IsNullOrWhiteSpace(path))thrownewArgumentNullException("path");锁(_lock){_storage[path]=Tuple.Create(newObjectInfo{Created=DateTime.Now,Modified=DateTime.Now,Path=path},(object)value);if(_storage.Count>MaxObjects)_storage.Remove(_storage.OrderByDescending(kvp=>kvp.Value.Item1.Created).First().Key);}returntrue;}3、确定一个队列,确定时间消费日志。_storage=objectStorage;_serializer=serializer;if(processQueueInterval.HasValue)_processQueueInterval=processQueueInterval.Value;_queueTimer=newTimer(OnProcessQueue,null,queueStartDelay??TimeSpan.FromSeconds(2),_processQueueInterval);}这里删除的时候也需要锁。publicboolDeleteObject(stringpath){if(String.IsNullOrWhiteSpace(path))thrownewArgumentNullException("path");lock(_lock){if(!_storage.ContainsKey(path))returnfalse;_storage.Remove(path);}returntrue;}publicIEnumerableGetObjectList(stringsearchPattern=null,int?limit=null,DateTime?maxCreatedDate=null){if(searchPattern==null)searchPattern="*";if(!maxCreatedDate.HasValue)maxCreatedDate=DateTime.MaxValue;varregex=newRegex("^"+Regex.Escape(searchPattern).Replace("\\*",".*?")+"$");lock(_lock)return_storage.Keys.Where(k=>regex.IsMatch(k)).Select(k=>_storage[k].Item1).Where(f=>f.Created<=maxCreatedDate).Take(limit??Int32.MaxValue).ToList();}总结1.使用字典。多线程向内存中添加数据;2.达到一定数量后,批量保存数据。3.使用锁来保证字典的安全运行。