我希望有人可以对我可能发生的事情有所了解。以下是最新动态的摘要。
我有一个应用程序,可以做很多“东西”。它是一个非常庞大的应用程序,使用许多线程进行大量的数字运算。有几个定时器使用。在很长一段时间内,计时器停止一直调用已经过的处理程序。
例如:我有一个定时器设置为每秒过去一次。几个小时后,计时器开始随机触发。如果我没有重新启动应用程序,性能会降低,定时器会在稍后启动,最后会变为3或4秒,从而迫使我重新启动应用程序。我无法识别任何泄漏。 CPU使用率不会上升,内存不会上升,服务器也不会接近最大值。谁能给我一些关于可能导致这种情况的想法?
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if (seconds > 0)
{
seconds--;
timer.Start();
}
}
答案 0 :(得分:5)
你是否有可能耗尽线程池?大多数计时器使用线程池线程调用处理程序。如果所有线程池线程都在使用中,它将排队,直到有一个可用。
如果是这种情况,请将一些处理切换为使用自己的线程,而不是线程池线程。
要测试你是否正在耗尽线程池,请启动一个后台线程,定期(每秒几次)检查ThreadPool.GetAvailableThreads
并在可用时很小时记录一条消息(即使它实际上从未实际为零时也是如此)你检查,如果它有时接近零,那么这可能是问题所在。)
可以使用ThreadPool.SetMaxThreads
更改池的大小,尽管这可能不是最佳解决方案。如果您正在使用线程池线程来执行更长时间的运行任务,请将其停止。对于长时间运行的任务,请使用自己的线程。
答案 1 :(得分:1)
您使用的计时器类非常重要
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
但我不认为问题是计时器本身, 例如,尝试使用相同的计时器类
创建一个应用程序仅将当前DateTime写入日志文件
让它运行很长一段时间,你会发现没有这么长的3/4秒延迟
检查您的计时器代码并检查是否同时访问了共享资源, 也许Timer是正常的,但是事件处理函数或函数使用的“某些东西”存在瓶颈
答案 2 :(得分:0)
听起来好像它可能不是真正相同的计时器,因此这里“泄露”的资源是GDI句柄。
答案 3 :(得分:0)
可能的解决方法:
DateTime mayContinue = DateTime.MinValue;
bool blockingUi = false;
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if( blockingUi )
{
if( DateTime.Now < mayContinue )
{
// Notify time remaining
// Update the UI with a BeginInvoke
}
else
{
blockingUi = false;
// Notify ready
// Update the UI with a BeginInvoke
}
}
}
private void BlockUi()
{
mayContinue = DateTime.Now.AddSeconds(30);
blockingUi = true;
}