DispatcherTimer随着时间的推移消耗CPU导致WPF视觉无法正确呈现

dis*_*rax 5 c# wpf cpu dispatchertimer

我有一个WPF应用程序,它使用DispatcherTimer更新时钟滴答.

但是,在我的应用程序运行约6小时后,时钟指针角度不再变化.我已经验证DispatcherTimer仍在使用Debug触发,并且角度值仍在更新,但屏幕渲染不反映更改.

我还验证了使用WPFPerf工具Visual Profiler,未标记时间,Tick(时间管理器)和AnimatedRenderMessageHandler(媒体内容)都在逐渐增长,直到消耗了近80%的CPU,但内存运行稳定.

hHandRT.Angle是对RotateTransform的引用

hHandRT = new RotateTransform(_hAngle);
Run Code Online (Sandbox Code Playgroud)

此代码可以完美地运行大约5个小时的直接运行但在此之后它会延迟并且角度变化不会呈现给屏幕.有关如何解决此问题的任何建议或您可能知道的任何可能的解决方案.

.NET 3.5,Windows Vista SP1或Windows XP SP3(两者都显示相同的行为)

编辑:添加时钟节拍功能

//In Constructor
...
_dt = new DispatcherTimer();
_dt.Interval = new TimeSpan(0, 0, 1);
_dt.Tick += new EventHandler(Clock_Tick);
...

 private void Clock_Tick(object sender, EventArgs e)
        {

            DateTime startTime = DateTime.UtcNow;
            TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById(_timeZoneId);
            _now = TimeZoneInfo.ConvertTime(startTime, TimeZoneInfo.Utc, tst);
            int hoursInMinutes = _now.Hour * 60 + _now.Minute;
            int minutesInSeconds = _now.Minute * 60 + _now.Second;
            _hAngle = (double)hoursInMinutes * 360 / 720;
            _mAngle = (double)minutesInSeconds * 360 / 3600;
            _sAngle = (double)_now.Second * 360 / 60;
            // Use _sAngle to showcase more movement during Testing.
            //hHandRT.Angle = _sAngle;
            hHandRT.Angle = _hAngle;
            mHandRT.Angle = _mAngle;
            sHandRT.Angle = _sAngle;

            //DSEffect
            // Add Shadows to Hands creating a UNIFORM light
            //hands.Effect = textDropShadow;
        }
Run Code Online (Sandbox Code Playgroud)

随着时钟滴答中发生太多事情,我正在尝试这种调整,看它是否有帮助.太糟糕了,它需要花费5个小时来表现自己:(

  //DateTime startTime = DateTime.UtcNow;
  //TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById(_timeZoneId);
  //_now = TimeZoneInfo.ConvertTime(startTime, TimeZoneInfo.Utc, tst);
  _now = _now.AddSeconds(1);
Run Code Online (Sandbox Code Playgroud)

Ran*_*ngy 5

您说您每次都在创建Clock类的实例吗?请注意,.NET中的计时器将生根,以防止自己被垃圾回收。它们将继续触发直到您自己停止它们为止,并且它们将使Clock对象保持活动状态,因为它们在计时器tick事件中被引用。

我认为正在发生的事情是,您创建的每个Clock都会启动另一个计时器。起初,您每秒仅触发1个事件,但随后您又添加了另一个计时器,并每秒获得2个事件,它们以这种方式继续累积。最终,您看到Tick处理程序和AnimatedRenderMessageHandler在CPU中上升,直到它们停滞不前并无法更新屏幕。这也可以解释为什么增加计时器触发频率会使您的症状更早出现的原因。

解决方法应该很简单:完成Clock对象后,只需停止或处置DispatcherTimer。