如何在WPF中使用调度程序定时器精确控制帧速率?

2023-12-01

当我尝试使用 System.Windows.Threading.DispatcherTimer 实例控制 WPF 中的帧速率时遇到问题。

为了尝试 DispatcherTimer 的有效性,我创建了一个简单的 WPF 演示,其中包含一个窗口,其中有一个文本框和一个按钮。单击该按钮时,DispatcherTimer 实例开始根据文本框中的双数字作为时间间隔进行计时,并且 StopWatch 同时启动,计数器变量在每个 DispatcherTimer 计时时增加 1。当 StopWatch.ElaspedMilliSeconds > 1000(超过 1 秒)时,计时器停止计时,秒表也重置,弹出消息框显示计数器的值。

因此,如果我输入 33.3(1000/30),计数器值应该约为 30。但结果是20左右。我请求帮助是否有人可以帮助检查我下面的源代码中似乎有什么问题。提前致谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TimerDemo
{
   public partial class MainWindow : Window
   {
      private System.Windows.Threading.DispatcherTimer _timer = new System.Windows.Threading.DispatcherTimer();
      public MainWindow()
      {
         InitializeComponent();
         double ticks = 0L;
         System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

         int frameCount = 0;

         //There is a textbox "txtTicks" which accepts a millisecond value
         //And a button "btn", by clicking the button the dispatchertimer & 
         //stopwatcher are started.
         _timer.Tick += (sender, e) =>
         {
            frameCount++;
            System.Diagnostics.Debug.WriteLine(watch.ElapsedMilliseconds);
            if (watch.ElapsedMilliseconds > 1000)
            {
               _timer.Stop();
               watch.Reset();
               MessageBox.Show(string.Format("Already 1 second! FrameCount: {0}", frameCount));
               frameCount = 0;
            }
         };

         this.btn.Click += (sender, e) =>
         {
            double.TryParse(this.txtTicks.Text, out ticks);
            if (ticks != 0.0)
            {
               _timer.Interval = TimeSpan.FromMilliseconds(ticks);
            }
            _timer.Start();
            watch.Start();
         };
      }
   }
}

运行结果如下(Stackoverflow的菜鸟,还不能上传图片):

https://i.stack.imgur.com/u6W2s.png


由于 WPF(和大多数其他渲染引擎)并不需要相同的时间来渲染每一帧,并且由于不同的计算可以进一步延迟帧之间的间隔,因此您使用CompositionTarget.Rendering来“计时”渲染间隔,但您仍然可以使用“挂钟”计时器来update定期、严格控制的时间间隔进行比赛。

在优秀的书“游戏编程模式”(在线免费提供)中,您可以找到非常有用的内容游戏循环模式.

在其完整形式中,这就是您将在处理程序中放入的内容CompositionTarget.Rendering事件(伪代码):



  double current = getCurrentTime();
  double elapsed = current - previous;
  previous = current;
  lag += elapsed;

  processInput();

  while (lag >= MS_PER_UPDATE)
  {
    update();
    lag -= MS_PER_UPDATE;
  }

  render();
  

在 C# 中,您可以实现getCurrentTime()要么通过调用DateTime.Now或通过使用Stopwatch.Elapsed, 例如。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在WPF中使用调度程序定时器精确控制帧速率? 的相关文章

  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • STM32F4 定时器 - 计算周期和预分频,以生成 1 ms 延迟

    我在用STM32F407VGT6 with CubeMX 因此 我从通用定时器开始 但我被预分频值和周期值所困扰 基本上我想每隔一段时间生成一个定时器中断n 其中 n 1 2 3 ms 并执行一些任务 计算周期和预分频值的公式有很多变化 公
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐

  • 数据库:图像文件为 blob 还是文件路径?

    我知道这个问题已经被问过很多次了 I read this整篇文章 但仍然没有达到一个点 我正在制作一个网站 允许用户下载壁纸和歌曲 除了我之外 没有人会上传这些壁纸 歌曲 我的意思是说用户不会上传它们 现在 每个文件平均为 6Mb 歌曲 现
  • 当前上下文中不存在名称“sr”

    我正在遵循微软的例子site用于从文本文件中读取 他们说这样做 class Test public static void Main try using StreamReader sr new StreamReader TestFile t
  • Android:编译 9 补丁文件以在可绘制文件夹之外使用?

    我需要从可绘制文件夹外部加载 9 个补丁文件 例如 这样我的应用程序就可以从服务器下载新的皮肤 我发现在制作 apk 时 会编译存储在可绘制文件夹中的 9 补丁图像 从资产文件夹中读取的完全相同的文件没有 9 补丁块 因此 制作 apk 的
  • 将 X.509 证书从十六进制形式转换为 .cer 格式

    如何将 X 509 证书从十六进制转储形式转换为 CER 格式 此外 是否应该首先从十六进制转储中删除空格分隔符 谢谢 你可以使用ASN 1 编辑器 它有一个数据转换器 可以将 HEX 格式的数据转换为 PEM 格式的数据 源代码也可用 因
  • C# 解密加密文件时出现“Bad Data”异常

    嘿 我对加密和解密很陌生 说实话 甚至对 C 语言也很陌生 基本上 我有一个 TCP 聊天服务器 可以 保存 日志并加密文本文件 这就是我加密的方式 基于 MSDN 示例 public static void EncryptFile str
  • 使用mechanize登录megaupload

    我正在尝试使用以下代码登录megaupload 我的问题是 如何才能成功登录 我在代码末尾打印出当前的 URL 但是当我运行脚本时 它只返回 www megaupload com import mechanize import cookie
  • 检索和使用 tkinter 组合框选择

    我正在为一个定制计算器组装一个 GUI 它可以自动将某些测量单位转换为其他测量单位 我想返回所选的实际文本 以便我可以根据用户选择的任何内容编写 if 语句 如何让 python 返回实际值而不是我现在得到的值 每当我测试此代码时 我都会收
  • 为什么 AES 的不同实现会产生不同的输出?

    我觉得我对哈希函数及其所涉及的契约有很好的理解 输入 X 上的 SHA1 将始终产生相同的输出 您可以使用 Python 库 Java 库或笔和纸 它是一个函数 它是确定性的 我的 SHA1 与你的 Alice 和 Bob 的相同 据我了解
  • Oracle返回count的最高值

    为清楚起见进行了编辑 因此 我使用 Oracle SQL Developer 并设置了相当基本的数据库 我正在尝试计算两个合并列的重复项总数 并返回数量最高的字段 我使用的是 Oracle IDE 19 2 1 这是我到目前为止所拥有的 s
  • Azure DevOps Nuget 管道步骤中的 Nuget 包描述

    是否可以为 Azure DevOps Pipeline 中添加的 NuGet 包添加描述 Azure DevOps Nuget 管道步骤中的 Nuget 包描述 众所周知 当我们打包 nuget 包时 csproj文件 nuget将从文件中
  • 对于 Marshmallow 或更高版本中的窗口类型 2010,Android 权限被拒绝

    我正在尝试做Chathead类型过度绘制通过安卓服务在我的应用程序上 如下图所示 这个聊天头应用程序适用于 Android 版本 5 或更低版本 kitkat 棒棒糖等 但我在 Marshmallow 和更高版本中尝试它 然后收到此错误 a
  • 绘制图形在 VB.net 中消失

    我有一个简单的程序 您可以使用 FillEllipse 和 FillRectangle 在屏幕上绘制 我的问题是 当您将另一个窗口拖动到屏幕的一小部分时 该部分将被删除 当您将另一个窗口拖过 放开 然后将其拖回时 就会发生这种情况 有没有什
  • 在 Python 中使用 rarfile 从 RAR 存档中提取单个文件

    我有一个包含 2 个文件的 RAR 存档 但我只想提取一个 我在另一个答案中发现我可以使用rarfile包 根据文档包含extract功能 但是 当我尝试运行脚本时 我得到了FileNotFoundError WinError 2 以及以下
  • 在脚本中使用电子表格标准函数?

    当我编写脚本并想要使用标准函数时 例如WEEKNUM 这是否可以直接进行 或者我是否必须通过以下方式将公式触发到另一个字段 setFormula formula 然后读取相关单元格的内容 您描述的方法确实可行 但根本效率不高 因为它需要多次
  • 如何使用scikit线性回归模型同时求解多个独立时间序列

    我尝试使用 sklearn 线性回归模型同时预测多个独立时间序列 但我似乎无法正确预测 我的数据组织如下 Xn是一个矩阵 其中每行包含 4 个观测值的预测窗口 yn是每行的目标值Xn import numpy as np training
  • 登录 google firebase 帐户时出现错误 16 问题

    如您所见 这是我的代码 主要是从谷歌文档复制的 用于谷歌登录身份验证 问题是 当我单击登录按钮时 它会抛出一个名为 16 的错误 抱歉发布图像 我在发布代码时遇到问题 希望有人可以帮助我解决此问题 依赖关系 对于火力基地 implement
  • 收到“阅读器关闭时调用 Read 的尝试无效”

    我有以下代码 此处使用伪值以提高可读性 其中第一个连接返回大量数据 数千行 SqlDataReader 通过以下方式一一读取它们reader Read 然后打开一个新连接以使用新值更新每一行 using SqlConnection conn
  • 如何在 VB.NET 窗体的默认实例中调用方法而不是实例化另一个方法?

    当实例化的类调用父表单类中的方法时 VB NET 启动表单类的一个新实例 而不是调用活动实例的方法 我如何告诉它我只有一个表单类的实例 或者我不想创建表单的新实例而只想调用已经处于活动状态的表单上的方法 这是使用线程时的一个经典问题 表单实
  • 反序列化派生类时如何忽略基类 JsonConverter?

    我有一个抽象基类 JsonConverter typeof Converter public abstract class TextComponent public bool Bold get set public TextComponen
  • 如何在WPF中使用调度程序定时器精确控制帧速率?

    当我尝试使用 System Windows Threading DispatcherTimer 实例控制 WPF 中的帧速率时遇到问题 为了尝试 DispatcherTimer 的有效性 我创建了一个简单的 WPF 演示 其中包含一个窗口