C# for和foreach解析
来源:互联网 发布:马六甲 知乎 编辑:程序博客网 时间:2024/06/06 19:53
首先上一部分代码:
private static List<AllShop> allShop = new List<AllShop>();//临时存放推送商场 public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { writestr("服务启动"); timer1.Enabled = true; timer1.Interval = basetime; get_Shops(); for (int i = 0; i < allShop.Count; i++) { //为每个shop开启新线程 ThreadStart threadStart = new ThreadStart(delegate () { try { pushDDXX(allShop[i]); writestr(allShop[i].getShopID() + "线程结束"); } catch (Exception ex) { writestr("OnStart_"+ i + ":"+ex.Message.ToString()); } }); Thread thread = new Thread(threadStart); thread.Start(); } }
看出有什么问题了吗?
这是报错日志:
2017-04-13 09:46:30
OnStart_16:索引超出范围。必须为非负值并小于集合大小。
这里的
allShop.Count是等于16的。所以理论上不会出现上述问题,不可能索引超出范围。
这是更改后的:
private static List<AllShop> allShop = new List<AllShop>();//临时存放推送商场 public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { writestr("服务启动"); timer1.Enabled = true; timer1.Interval = basetime; get_Shops(); foreach (var shop in allShop) { //为每个shop开启新线程 ThreadStart threadStart = new ThreadStart(delegate () { try { pushDDXX(shop); writestr(shop.getShopID() + "线程结束"); } catch (Exception ex) { writestr("OnStart_"+ shop.getShopID() + ":"+ex.Message.ToString()); } }); Thread thread = new Thread(threadStart); thread.Start(); } }
后来经过断点调试,发现在多线程中,for循环的i+1后,前面代码里的i也会跟着改变。for循环停止的时候i=16,这时候不管在哪个线程,只要没有走完i都是16。外层循环结束的时候,里面的执行方法不一定结束了。
这个错误在于没有理解for循环和进程的关系,以为最后i=16的时候不会走进去,其实这是个误区,i=16的时候只是不再产生新的进程,但所有进程都使用一个全局的i,所以最终出现了writestr(allShop[i].getShopID() + "线程结束");导致错误,改法就是把变量作为参数传进去。
或者 用ParameterizedThreadStart委托代替ThreadStart委托并在匿名委托方法体中用委托参数代替i用thread[i].Start(i)来启动线程
1 0
- C# for和foreach解析
- c#中foreach和for
- C# 中 for和foreach 性能比较
- c# foreach 和for循环比较
- C# Parallel.For和Parallel.ForEach学习
- c# for与foreach
- C# 中 for和foreach 性能比较,提高编程性能
- C#访问Xml 关于Foreach 和For循环
- 对比C#中for和foreach循环的性能
- C#中for和foreach循环的性能
- C# 中 for和foreach 性能比较,提高编程性能
- 对比C#中for和foreach循环的性能
- 黑马程序员--C#中for和foreach的区别
- C# 中 for和foreach 性能比较,提高编程性能
- C# for、while和foreach遍历产生GC
- C#学习你需要知道的---(For和Foreach)
- for 和 foreach区别
- for 和 foreach区别
- Cookie与Session
- Tomcat 7 的七大新特性
- Java设计模式(代理模式)
- CSS中伪元素 :before 和 :after 的使用
- 关于大型网站技术演进的思考(一)--存储的瓶颈(1)
- C# for和foreach解析
- 关于大型网站技术演进的思考(二)--存储的瓶颈(2)
- 关于大型网站技术演进的思考(二)--存储的瓶颈(3)*
- 自己实现简单对象关系库之Database的实现
- 解决JS传递中文参数乱码问题
- 关于大型网站技术演进的思考(四)--存储的瓶颈(4)
- (ros/catkin) ××/××.h: No such file or directory
- 数据库事物
- 纯css一页显示多个块的水平滑动效果