Collection学习1
User
public class User { public int UserId { get; set; } public string UserName { get; set; } }
Use CurentBag
public class UserManager { private static object lockFlag = new object(); private static int maxUserId = 0; public static int MaxUserId { get { return maxUserId; } } public static int GetNextUserId() { lock (lockFlag) { maxUserId++; return maxUserId; } } public static void AddUser() { int userId = GetNextUserId(); if (userId % 1000 == 0) { Console.WriteLine("UserId: " + userId.ToString() + " DT:" + DateTime.Now.ToString("HH:mm:ss.fff")); } User user = new User() { UserId = userId, UserName = "User" + userId.ToString() }; } public static List<User> GetUsers(int maxUserId) { List<User> result = new List<User>(); for(int i=0;i<Users.Count;i++) { User user = Users.ElementAt(i); if (user.UserId > maxUserId) { result.Add(user); } } return result; } public static ConcurrentBag<User> Users = new ConcurrentBag<User>(); }
Test
class Program { static void Main(string[] args) { int thCount = 500; Console.WriteLine("UserId: 0 " + " DT:" + DateTime.Now.ToString("HH:mm:ss.fff")); while (thCount > 0) { Thread th = new Thread(new ThreadStart(Test)); th.Name = "TH" + thCount.ToString(); th.Start(); thCount--; } } public static void Test() { int maxId = 0; int count = 0; while (true) { if (count % 2 == 0) { DateTime dt1 = DateTime.Now; UserManager.AddUser(); DateTime dt2 = DateTime.Now; int usedMS = dt2.Subtract(dt1).Milliseconds; //Console.WriteLine("AddComment:" + usedMS.ToString() + "ms " + DateTime.Now.ToString("hh:mm:ms")); } else { DateTime dt1 = DateTime.Now; List<User> result = UserManager.GetUsers(maxId); DateTime dt2 = DateTime.Now; int usedMS = dt2.Subtract(dt1).Milliseconds; //Console.WriteLine("GeComments:" + result.Count.ToString()+" Used " + usedMS.ToString() + "ms "+DateTime.Now.ToString("hh:mm:ms")); if (result.Count > 0) { maxId = result.Select(p => p.UserId).Max(); } } count++; } } }
Use List
public class UserManager { private static object lockFlag = new object(); private static int maxUserId = 0; public static int MaxUserId { get { return maxUserId; } } public static int GetNextUserId() { lock (lockFlag) { maxUserId++; return maxUserId; } } public static void AddUser() { int userId = GetNextUserId(); if (userId % 1000000 == 0) { Console.WriteLine("UserId: " + userId.ToString() + " DT:" + DateTime.Now.ToString("HH:mm:ss.fff")); } User user = new User() { UserId = userId, UserName = "User" + userId.ToString() }; } public static List<User> GetUsers(int maxUserId) { List<User> result = new List<User>(); for(int i=0;i<Users.Count;i++) { User user = Users[i]; if (user.UserId > maxUserId) { result.Add(user); } } return result; } public static List<User> Users = new List<User>(); }
List Result:
静态的List是类型安全的,但不可以使用Foreach对其进行遍历。每次foreach操作,都会检查遍历对象的版本,若版本发生变化,则会抛出异常。
从性能来看,List比ConcurrentBag要好,
从实现来看,List只有静态时才安全,否则需要自己实现同步和锁定。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现