我办公室的程序员在Windows窗体中编写了一个非常大的应用程序。无论如何,他在使用大约12小时后放慢速度时遇到了麻烦。我们已经确认它是实际的事件循环,最终运行缓慢而不是事件触发后的代码。例如,即使输入文本框也会非常慢。他有几个套接字通信线程,我们已确认它们以正常速度运行。我唯一能想到的是他在整个应用程序中有几个System.Timers.Timer实例。他们可能是问题吗?通常在没有人使用它约5或6个小时之后,程序会变慢。
我知道可能有很多可能存在的问题。我们只需要从哪里开始寻找一些建议。我已经尝试了所有显而易见的事情。
还有一件事需要提及。他的架构由一个基本形式组成,其中包括一个控件,每个页面都有3个定时器,所有其他形式都继承自这个基本形式。这些表单大概有15个左右,所有表单都在启动时加载到内存中。我们这样做了,因为客户抱怨在第一次花几秒钟之间切换表格。每个表单都有五十到一百个我们为他编写的控件实例,它可以完成所有后端工作。在这个控件中有一个静态计时器和一个静态线程 - 因为只有一个实例,无论控件的实例有多少都在内存中,我无法想象那些是问题。基本形式的计时器也是静态的。
我无法保证他的代码的效率,但它在我们的办公室运行得非常好,并且在现场运行了5到6个小时。
有什么想法吗?
编辑:
我刚刚和现场的那个人谈过,他问道。 1,其中一个静态计时器的事件处理程序不是静态的 - 静态计时器访问实例方法的可能性对我来说似乎很奇怪。其次,计时器的AutoReset设置为true。
更新
好的,我今天终于和那个人一起看了一些代码。
他有几个他班级的静态成员,即计时器,一些按钮和用户控件。然后在构造函数中,他在每个静态成员上使用new运算符而没有静态bool isInit标志。
换句话说,每次创建新表单时都会初始化静态成员,但只引用了最初初始化的表单。但是,我认为表单容器持有对旧对象的引用,因此旧对象永远不会被删除。另外,如果在更改静态成员的引用时删除对象,那么容器的这种别名是不是很糟糕?无论哪种方式,坏的泄漏或坏的别名都会导致问题。我希望这是唯一的问题。我让他解决了所有问题,然后我们将再次测试。
为了增加对伤害的侮辱,他正在调用GC.KeepAlive(静态计时器),它在构造函数中有一个新的引用。所以,他有21个计时器在运行。
答案 0 :(得分:2)
让它保持运行,等到它变慢,连接调试器,逐步查看问题区域中哪些线路很慢。
编辑:
如果网站上的速度很慢,那么,如果产品是针对特定客户端的,那么您应该构建一个尽可能与客户端匹配的参考环境。这对未来都很有用,现在可用于识别可能导致问题的系统之间的差异。
我确实有一个类似的声音问题,我们在不同机器上的几个服务之间的后台线程上对套接字执行了一些远程处理。不幸的是我不记得确切的细节(叹息)。我记得我们一直在请求设定的时间间隔但是,服务的响应时间随着时间的推移变慢,最终响应时间超出设定的时间间隔。对于前1000个左右的调用来说这很好,.Net保持了我们期待的回调量不断增长的堆栈。但是,最终这个列表达到了一些内部限制并且消息泵冻结了,包括客户端GUI上的所有绘图。通过确保在我们得到回复之前不会打电话来解决这个问题。这种竞争条件可能是也可能不是你所经历的,但我认为值得一提。