首页 > 代码库 > 解决点击关闭按钮,应用程序退出时,系统爆出“集合已修改,可能无法执行枚举操作”异常的相关思路

解决点击关闭按钮,应用程序退出时,系统爆出“集合已修改,可能无法执行枚举操作”异常的相关思路

     这两天在优化升级公司的一个业务系统时,更改了一下窗体关闭事件中的一句代码,由system.Enviromen.Exit(0)改为了Application.Exit();但是这时候问题就出现了,当点击系统右上角关闭按钮的时候,会爆出“集合已修改,可能无法执行枚举操作”的异常。如下图所示:
     这是什么原因造成的呢?问了一下度娘,出现“集合已修改,可能无法执行枚举操作”这种异常大部分都是因为误用foreach语句引起的,foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等)。要避免这个问题,就应该使用for循环。以前没有考虑过对collection类型对象操作时for 和foreach的区别,总感觉foreach更方便一些。于是写了个foreach循环来验证一下这种说法,用foreach来遍历一个list,之后在foreach体内又对其添加,表面上逻辑和写法看着没错,但在运行时确实了出现异常。
 
      仔细排查了一下相关程序,没有发现哪使用了foreach,但是这种问题还是一直在出现。不过,在重现的过程中,发现了一个细节,就是”确定要离开系统吗?“的提示框会出现两次,点击关闭按钮之后,会弹出提示框,点击确定按钮,后会再次,弹出提示,再次点击确定按钮后,就爆异常了。发现这个细节后,突然意识到,这个异常的产生可能跟,弹出两次对话框有关系。正常情况下,应该弹出一次。
      现在问题的焦点是为什么会触发两次确认对话框呢?应该跟Application.Exit()这句代码有关系。Application.Exit()在MSDN上给出的含义是:停止在所有线程上运行的所有信息循环,并关闭应用程序的所有窗口。
     这下明白了,意思就是说:当执行Application.Exit();的时候会再次触发窗体关闭事件,也就是formclosing事件,从而引发死循环。
     认识到问题所在后,调整了一下写法:
     即把Application.Exit();放在formClosed事件里。在主窗体关闭后,再执行程序退出。
     再次,编译系统后,点击关闭按钮,系统正常退出。至此,问题得到了完美解决。

解决点击关闭按钮,应用程序退出时,系统爆出“集合已修改,可能无法执行枚举操作”异常的相关思路