2014-10-07 208 views
1

有没有办法在WPF来确定最佳的UI更新率,使WPF确定最佳的UI更新率

  1. 没有帧被跳过,
  2. UI停留负责。

对于很多工作来说,当渲染过程无法跟上时,通知UI某些值已经改变是没有意义的。事实上,我注意到当我尝试更新太频繁时,UI无响应,只显示一小部分帧(例如InvalidateVisual()被称为10次,但只显示一个新帧)。相反,我更喜欢UI以本地渲染速率更新。

到目前为止,我已经尝试过使用DispatcherTimer,但即使我将优先级降低到背景,如果更新速率过高,更新方法的调用次数也会比渲染发生时的次数要多(帧被跳过)。但是这个速度显然取决于硬件和屏幕上的元素数量。如果我进一步减少优先级,定时器根本不会被调用(可能是因为有后台线程运行来更新值)。

亚历

回答

1

我只是写了一个快速测试,看看有什么帧率我得到一个测试的.Net WPF应用程序。

我看到每秒60-63帧之间的速率,显示器刷新频率是60赫兹,所以我想我看到的是用本地速率更新UI。

我写这个使用CompositionTarget.Rendering事件,并实现了它的行为,并在一个非常简单的MVVM风格应用它连接到一个TextBlock:

XAML:

<TextBlock> 
    <i:Interaction.Behaviors> 
     <views:FrameRateBehavior /> 
    </i:Interaction.Behaviors> 
</TextBlock> 

C#代码:

public sealed class FrameRateBehavior : Behavior<TextBlock> 
{ 
    private readonly Queue<long> _ticks = new Queue<long>(); 

    public FrameRateBehavior() 
    { 
     _ticks = new Queue<long>(); 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     CompositionTarget.Rendering += CalculateFrameRate; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 

     CompositionTarget.Rendering -= CalculateFrameRate; 
     _ticks.Clear(); 
    } 

    private void CalculateFrameRate(object sender, EventArgs e) 
    { 
     var now = DateTime.Now; 
     var endTime = now.Ticks; 
     var startTime = now.AddSeconds(-1).Ticks; 

     while (_ticks.Any()) 
     { 
      if (_ticks.Peek() < startTime) 
      { 
       _ticks.Dequeue(); 

       continue; 
      } 

      break; 
     } 

     _ticks.Enqueue(endTime); 
     var count = _ticks.Count; 

     AssociatedObject.Text = "FPS: " + count; 
    } 
} 
+0

谢谢。 'CompositionTarget.Rendering'事件看起来很有希望。我移动了代码以将UI更新到此事件中,并立即显示更新。如果我的窗口中有很多UIElements,帧率会严重下降 - 因此会自动限制更新。 – LionAM 2014-10-07 13:58:18

+0

'UIElements在我的窗口....' - 是的帧速率会下降,当有一个'很多'... – AwkwardCoder 2014-10-07 14:12:38

+0

请记住,你不想'InvalidateVisual()',除非你的控件的大小更改。如果它们的大小相同,则创建一个'DrawingGroup'会更有效率,因此在'OnRender()'期间将其放置在可视化树中。无论什么时候,你都可以通过DrawingGroup.Open()来绘制新的命令,并且WPF只会更新UI的那部分。 – 2017-06-10 07:34:38